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:
-
The
MediaPlayer
interface includes bothplay_audio
andplay_video
methods. -
The
AudioPlayer
class implements theMediaPlayer
interface but leaves theplay_video
method empty, which is not meaningful for audio players. -
The
VideoPlayer
class also implements theMediaPlayer
interface but leaves theplay_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:
-
We have separate interfaces,
AudioPlayer
andVideoPlayer
, each containing only the methods relevant to their specific responsibilities. -
Clients, such as
SimpleAudioPlayer
andSimpleVideoPlayer
, 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.