Let’s back to article of ISP and take a this implementation:
interface Transport {
transport (Point A, Point B, int peopleCount)
transport (Point A, Point B, List<Package> packages)
}
Car implements Transport {
transport (Point A, Point B, int peopleCount) {...}
transport (Point A, Point B, List<Package> packages) {throw UnsupportedOperationException}
}
Parcelobus implements Transport {
transport (Point A, Point B, int peopleCount) {throw UnsupportedOperationException}
transport (Point A, Point B, List<Package> packages) {...}
}
Let’s see how the implementation/classes will be used in code:
if (transporter instanceOf Car) {
transporter.transport(pointA, pointB, numberOfPeople);
}
We need to check what type of object is to invoke the method! Crazy. Even more crazy thing is to use polymorphism in that way:
try {
transporter.transport(pointA, pointB, numberOfPeople);
} catch (UnsupportedOperationException ex) {
//do nothing
}
In both cases is not a true polymorphism and creepy code. Smart devs can use introspection … but let’s not get sunk ;p
What we can do to avoid that creepy code? Add additional methods to distinguish between behaviors/types:
interface Transport {
transport (Point A, Point B, int peopleCount) --consider generic
transport (Point A, Point B, List<Package> packages)
canTransportPeople() //or the worst version isACar()
canTransportPackages() //or the worst version isAParcelobus()
}
The interface looks bad, but the usage is cleaner now:
if (transport.canTransportPeople()) {
transport.transport(pointA, pointB, numberOfPeople);
}
Not true polymorphism, either.
Neither of the above solutions is good. We create workarounds to fix the bad design – an interface that has many behaviors. Which different behaviors are used by different classes/objects/things?
If you ever see a similar pattern in your project you will know that there is something wrong. You will be aware of what goes wrong.
Now let’s look at how it should be designed at the beginning <>
-The source of the problem is that interface Transport has/is responsible for many behaviors. In this particular case, we have a transport of people and transport of packages. Transport interface is used in different contexts. In the application code it is reflected in many conditions in various application places.
–The bigger the interface is/has more behaviors there will be more if conditions, and Transport will appear in various places application code.