SOLID Principles (Series) [PART 4]
SOLID - make Object-Oriented designs more understandable, flexible and maintainable.
![SOLID Principles (Series) [PART 4]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1666673548073%2FH3QdkOhn-.jpg&w=3840&q=75)
Senior Android Engineer from Bangladesh. Love to contribute in Open-Source. Indie Music Producer.
If get to know something new by reading my articles, don't forget to endorse me on LinkedIn
What is ISP?
Segregation means keeping things separated, and the Interface Segregation Principle is about separating the Interfaces.
The principle states that many client-specific
interfacesare better than one general-purposeinterface.Clients should not be forced to
implementafunctionthey do no need.ISP splits
interfacesthat are very large into smaller and more specific ones so that clients will only have to know about thefunctionsthat are of interest to them.
Things to remember
Don’t depend on things you don’t need.
Interfacescontainingmethodsthat are not specific to it are called polluted or fatinterfaces. We should avoid them.Many client-specific
interfacesare better than one general-purposeinterface. When we have non-cohesiveinterfaces, the ISP guides us to create multiple, smaller, cohesiveinterfaces.
Let's continue with the example from LSP.
interface MediaPlayer {
fun playAudio(mediaContent : MediaContent)
}
interface VideoMediaPlayer : MediaPlayer {
fun playVideo(mediaContent : MediaContent)
}
class VLCMediaPlayer : VideoMediaPlayer {
@override fun playAudio(mediaContent : MediaContent) {...}
@override fun playVideo(mediaContent : MediaContent) {...}
}
class WinampMediaPlayer : MediaPlayer {
@override fun playAudio(mediaContent : MediaContent) {...}
}
Above example is okay by following LSP. But what if we add another media player called VideoOnlyMediaPlayer?.
class VideoOnlyMediaPlayer : VideoMediaPlayer {
@override fun playAudio(mediaContent : MediaContent) {...}
@override fun playVideo(mediaContent : MediaContent) {...}
}
And, That's where the problem occurs. VideoOnlyMediaPlayer is forced to implement playAudio() function.
Again what's the problem with this design from LSP?
New MediaPlayer called VideoOnlyMediaPlayer should support only video MediaContent. It was not designed to play audio MediaContent. Since VideoMediaPlayer extends MediaPlayer, all Classes who implement VideoMediaPlayer must implement the playAudio() function.
Which state that We're forcing client to implement unnecessary functions.
So, how do we solve this problem by following ISP?.
We can modify our VideoMediaPlayer not to be extended from MediaPlayer. In this case, clients who doesn't need support for audio MediaContent won't be forced to implement playAudio() function.
Clients who needs support for both audio & video MediaContent must implements MediaPlayer and VideoMediaPlayer at their own.
Let's get into the solution.
interface AudioMediaPlayer {
fun playAudio(mediaContent : MediaContent)
}
interface VideoMediaPlayer {
fun playVideo(mediaContent : MediaContent)
}
class VLCMediaPlayer : VideoMediaPlayer, AudioMediaPlayer {
@override fun playAudio(mediaContent : MediaContent) {...}
@override fun playVideo(mediaContent : MediaContent) {...}
}
class WinampMediaPlayer : AudioMediaPlayer {
@override fun playAudio(mediaContent : MediaContent) {...}
}
class VideoOnlyMediaPlayer : VideoMediaPlayer {
@override fun playVideo(mediaContent : MediaContent) {...}
}
So, what's the changes here?
AudioMediaPlayerandVideoMediaPlayeris now independentInterface, there is no dependency between them. [MediaPlayerrefactored toAudioMediaPlayer]New introduced
VideoOnlyMediaPlayersupports videoMediaContentonly. Thus,VideoOnlyMediaPlayeris not forced to implmenetplayAudio()function as there is no inter-connection betweenAudioMediaPlayerandVideoMediaPlayer.VideoOnlyMediaPlayersupport videoMediaContentonly.VLCMediaPlayersupport both audio & videoMediaContent.WinampMediaPlayersupport only audioMediaContentas we have expected.
Recap
The principle states that many client-specific
interfacesare better than one general-purposeinterface.Clients should not be forced to
implementafunctionthey do no need.ISP splits
interfacesthat are very large into smaller and more specific ones so that clients will only have to know about thefunctionsthat are of interest to them.
In the next & last article of this series, we will talk about Dependency Inversion Principle.
That's it for today. Happy Coding...




