The Interface Segregation Principle (ISP) says that a class shouldn’t be forced to implement interfaces it doesn’t use.
In other words, it’s better to have smaller, specific interfaces instead of one large interface with methods that aren’t relevant to all implementations.
Let’s look at an example of an ISP violation using a Device
interface.
interface Device {
powerOn(): void;
reboot(): void;
print(): void;
}
class Printer implements Device {
powerOn() {...}
reboot() {...}
print() {...}
}
class Monitor implements Device {
powerOn() {...}
reboot() {...}
print() {
throw new Error("Monitor doesn't support printing!");
}
}
The Device
interface has method print()
that only makes sense for devices
that can print.
The Monitor
class is now forced to implement print()
method, which can
either lead to errors or, in best case, unnecessary code.
We can follow ISP by extracting methods from the Device
interface into another
interface:
interface Device {
powerOn(): void;
reboot(): void;
}
interface PrinterDevice extends Device {
print(): void;
}
class Printer implements PrinterDevice {
powerOn() {...}
reboot() {...}
print() {...}
}
class Monitor implements Device {
powerOn() {...}
reboot() {...}
}
Printer
can implement both interfaces, while Monitor
only implements the
basic Device
interface. This keeps the classes clean and avoids forcing them
to implement unnecessary methods.
Find this post helpful? Subscribe and get notified when I post something new!