接口隔离原则是什么?

接口隔离原则(Interface Segregation Principle)是指客户端不应该被迫依赖于它不使用的方法。这个原则倡导我们要尽量缩小接口的范围,使得客户端的类不必去实现它们不需要的方法。

案例

让我们通过一个案例来帮助我们理解接口隔离原则。假设现在有一个播放器系统,我们定义了一个接口 Player 来表示播放器,同时还定义了 playAudio 和 playVideo 方法分别表示播放音频和视频文件的操作。

  1. public interface Player {
  2. void playAudio(MultiMediaFile file);
  3. void playVideo(MultiMediaFile file);
  4. }

在这个系统中,我们有各种各样的播放器,例如 MP3、MP4 等。这是 MP3 的实现:

public class MP3 implements Player {
    @Override
    public void playAudio(MultiMediaFile file) {
        // Our code for playing video files by MP3

    }

    @Override
    public void playVideo(MultiMediaFile file) {
        throw new UnsupportedOperationException("Unable to play the video file.");
    }
}

这是 MP4 的实现:

public class MP4 implements Player {
    @Override
    public void playAudio(MultiMediaFile file) {
        // Our code for playing audio files by MP4
    }

    @Override
    public void playVideo(MultiMediaFile file) {
        // Our code for playing video files by MP4
    }
}

我们可以看到,MP3 不支持播放视频文件,但它却依然要实现 playVideo 方法,并在方法中抛出了不可预料的异常。这不但违反了接口隔离原则,其实也违反了单一职责原则与里式替换原则。
我们可以将“大而全”的接口拆分成多个颗粒度更新的接口来解决这一问题:将 Player 接口拆分成 AudioPlayer 和 VideoPlayer。这是 AudioPlayer 的定义:

public interface AudioPlayer {
    void playAudio(MultiMediaFile file);
}

这是 VideoPlayer 的定义:

public interface VideoPlayer {
    void playVideo(MultiMediaFile file);
}

MP3 只支持播放音频文件,所以它只实现 AudioPlayer 接口:

public class MP3 implements AudioPlayer {
    @Override
    public void playAudio(MultiMediaFile file) {
        // Our code for playing audio files by MP3
    }
}

MP4 即支持播放音频文件,也支持播放视频文件,所以它同时实现 AudioPlayer 和 VideoPlayer 接口。

public class MP4 implements AudioPlayer, VideoPlayer {
    @Override
    public void playVideo(MultiMediaFile file) {
        // Our code for playing audio files by MP4
    }

    @Override
    public void playAudio(MultiMediaFile file) {
        // Our code for playing video files by MP4
    }
}

案例源码

可在 GitHub 上查看上述案例的完整代码。

参考资料

以下是本文参考的资料: