Interface Segregation Principle (ISP)
This is part of my SOLID Software Principles in Practice post.
ISP states that no client should be forced to depend on methods it does not use. Consider the following code snippet, which violates ISP:
interface Invader{
void bomb();
void swoop();
}
public final class Bomber implements Invader{
@Override
public void bomb() {
dropBombs();
}
@Override
public void swoop() {
// do nothing :(
}
}
public final class Swooper implements Invader{
@Override
public void bomb() {
// do nothing
}
@Override
public void swoop() {
initiateSwoop();
}
}
Above we have an Invader interface, which is designed so that all Invaders drop bombs as well as swoop down at the player - think Galaxian - However, our Bombers only drop bombs and our Swoopers only swoop, but each one is forced to implement a method that they don’t actually need. What we should do is segregate this overly fat interface and make it more granular like so:
interface BombingInvader {
void bomb();
}
interface SwoopingInvader {
void swoop();
}
public final class Bomber implements BombingInvader {
@Override
public void bomb() {
dropBombs();
}
}
public final class Swooper implements SwoopingInvader {
@Override
public void swoop() {
initiateSwoop();
}
}
If we later desire an Invader which both bombs and swoops, we can implement both interfaces like so:
public final class SwoopingBomber implements SwoopingInvader, BombingInvader {
@Override
public void bomb() {
dropBombs();
}
@Override
public void swoop() {
initiateSwoop();
}
}
Doing this leads to better decoupling of classes, which leads to the code being easier to refactor, maintain and read.