Interface Segregation Principle (ISP) | SOLID Principle - 4

Published on July 30, 2023

from abc import ABC, abstractmethod
 
# Problematic interface violating ISP
class MediaPlayer(ABC):
    @abstractmethod
    def play_audio(self):
        pass
 
    @abstractmethod
    def play_video(self):
        pass
 
class AudioPlayer(MediaPlayer):
    def play_audio(self):
        print("Playing audio...")
 
    def play_video(self):
        pass  # This is empty because audio players shouldn't play videos
 
class VideoPlayer(MediaPlayer):
    def play_audio(self):
        pass  # This is empty because video players shouldn't play audio
 
    def play_video(self):
        print("Playing video...")
 

In this code:

  1. The MediaPlayer interface includes both play_audio and play_video methods.

  2. The AudioPlayer class implements the MediaPlayer interface but leaves the play_video method empty, which is not meaningful for audio players.

  3. The VideoPlayer class also implements the MediaPlayer interface but leaves the play_audio method empty, which is not meaningful for video players.

This violates the ISP because clients (audio and video players) are forced to implement methods that are not relevant to their specific responsibilities.

To adhere to the ISP, you can split the MediaPlayer interface into separate interfaces for audio and video:

Example of ISP in action
from abc import ABC, abstractmethod
 
# Interfaces adhering to ISP
class AudioPlayer(ABC):
    @abstractmethod
    def play_audio(self):
        pass
 
class VideoPlayer(ABC):
    @abstractmethod
    def play_video(self):
        pass
 
# Clients implementing the specific interfaces
class SimpleAudioPlayer(AudioPlayer):
    def play_audio(self):
        print("Playing audio...")
 
class SimpleVideoPlayer(VideoPlayer):
    def play_video(self):
        print("Playing video...")
 

In this improved design:

  1. We have separate interfaces, AudioPlayer and VideoPlayer, each containing only the methods relevant to their specific responsibilities.

  2. Clients, such as SimpleAudioPlayer and SimpleVideoPlayer, implement the specific interfaces based on their requirements, and they are no longer forced to implement irrelevant methods.

This adheres to the Interface Segregation Principle, making the code more maintainable and ensuring that clients are only dependent on the interfaces they actually use.