SOLID Design Principles (ISP)

Abdullah Aimen
3 min readApr 7, 2019
Building a wall in the right way retains its strength

In the previous article, we talked about the third Principle of SOLID Principles series. we demonstrated an example to make everything clear and obvious.

Today, we are going to talk about the fourth principle…

Interface Segregation Principle (ISP)

Many client-specific interfaces are better than one general-purpose interface. No client should be forced to depend on methods it doesn’t use.

Which means, one giant interface should be split into many smaller and relevant interfaces so, that client can know about the interfaces that are relevant to them.

So, How we can apply the ISP?

Suppose we have different printer types and we need a common interface to deal with it. So we create an interface with all the methods expected from a current printer!

Which is like…

interface IPrinter {
fun printContent(content: String): Boolean
fun scanContent(content: String): Boolean
fun faxContent(content: String): Boolean
fun photoCopyContent(content: String): Boolean
fun printDuplexContent(content: String): Boolean
}

we will create a Cannon Printer which has the full functionality of IPrinter interface.

class CannonPrinter : IPrinter {
override fun printContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun scanContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun faxContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun photoCopyContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun printDuplexContent(content: String): Boolean {
System.out.println(content)
return true
}
}

now, if we need to add an Old-Printer with some functionality of IPrinter interface(not the full signature methods).

class DellPrinter : IPrinter {
override fun printContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun scanContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun faxContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun photoCopyContent(content: String): Boolean {
return false
}

override fun printDuplexContent(content: String): Boolean {
return false
}
}

As this printer doesn’t support duplex content copy or photo content copy we will return false but this will be violating the concept.

After Apply ISP:

interface IPrintScanContent {
fun printContent(content: String): Boolean
fun scanContent(content: String): Boolean
fun photoCopyContent(content: String): Boolean
}

interface IPrintDuplex {
fun printDuplexContent(content: String): Boolean
}

interface IFaxContent {
fun faxContent(content: String): Boolean
}
class DellPrinter : IPrintScanContent {
override fun printContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun scanContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun photoCopyContent(content: String): Boolean {
System.out.println(content)
return true
}
}
class CannonPrinter : IPrintScanContent, IFaxContent, IPrintDuplex {
override fun printContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun scanContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun photoCopyContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun faxContent(content: String): Boolean {
System.out.println(content)
return true
}

override fun printDuplexContent(content: String): Boolean {
System.out.println(content)
return true
}
}

And the implementation will be like…

fun main(args: Array<String>) {
var cannonPrinter = CannonPrinter()
lPrint(cannonPrinter.printContent("Print Content"))
lPrint(cannonPrinter.faxContent("Fax Content"))
lPrint(cannonPrinter.scanContent("Scan Content"))
lPrint(cannonPrinter.printDuplexContent("Print Duplex Content"))
lPrint(cannonPrinter.photoCopyContent("Photo Copy"))

System.out.println()
System.out.println()

var dellPrinter = DellPrinter()
lPrint(dellPrinter.printContent("Print Content"))
lPrint(dellPrinter.scanContent("Scan Content"))
lPrint(dellPrinter.photoCopyContent("Photo Copy"))

}

fun lPrint(data: Boolean) {
System.out.println(data)
}

As we saw, Instead of having one large Job class, a Staple Job interface or a Print Job interface was created that would be used by the Staple or Print classes, respectively, calling methods of the Job class. Therefore, one interface was created for each job type, which was all implemented by the Job class.

Summary

The ISP guides us to create many small interfaces with coherent functionalities instead of a few big interfaces with lots of different methods. When we apply the ISP, class and their dependencies communicate using focused interfaces, minimizing dependencies. Smaller interfaces are easier to implement, improving flexibility and the possibility of reuse.

Remember always you are a Programmer, not Plumper! Thanks for continuing the article. If you like it just clap and share!

References

Object-Oriented Programming

SOLID Principles

--

--