The Interface Segregation Principle (ISP)

Clients should not be forced to depend on methods that they do not use.

This principle deals with heavy interfaces. The clients of these heavy interfaces are forced to carry extra burdens. That is, they are subject to changes that are requested by other clients. Let's see an example of this.

Future Drone is a company that produces drones. Their research and development department has recently designed a drone that can fly and drive. There are two separate remote control devices for this drone—one controls its flying and the other controls its driving. Here is the design of their DroneController API:

Figure 6.2: The DroneController API

As you can see, both remote control devices can access the methods that they don't need. This is seriously wrong. Why? Because the engineers from Future Drone's R&D department work very hard and they make drones that can also sail. Now, they need to add a sail() method to the DroneController API so that SailRemoteControlDevice can make a drone sail, as shown in the following diagram:

Figure 6.3: New version of the DroneController API

Now, the new version of DroneController forces FlyRemoteControlDevice and DriveRemoteControlDevice to be recompiled and redeployed to all of those remote control devices. This is why the design of DroneController is seriously wrong!

Let's refactor it according to the ISP, as shown in the following diagram:

Figure 6.4: Segregated interface

As you can see, smaller interfaces are created for each device, respectively. This releases the unnecessary burdens that the DroneController API put on them. They are not affected by future changes on other interfaces.

However, this design still violates the SRP. DroneControllerManager, an implementation of DroneController, contains more than one reason of change. To make it conform with the SRP, DroneController should be faded out and deprecated. The fly(), drive(), and sail() implementations inside DroneControllerManager should also be moved into separate implementations of each smaller controller API, as shown in the following diagram:

Figure 6.5: Implementation conforming to the SRP

Façade design pattern: This pattern is a part of the Gang of Four (GoF) design patterns, categorized under structural design patterns. This pattern is used to provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher level interface that makes the subsystem easier to use.

In the following diagram, on the left-hand side, clients of a subsystem need to know the details of classes inside the subsystem. On the right-hand side, the Façade of the subsystem provides a unified interface to its clients and hides the implementation details of the subsystem. Changes inside the subsystem are not visible to the clients, as long as the APIs of the Façade stay the same:

Figure 6.6: Facade design pattern

If you think about this Façade design pattern and the ISP, it seems that what the ISP suggests you do is the opposite of how Façade works. Clearly, the Façade design pattern is a violation of the ISP, right? It depends on which level you are going to apply the Façade design pattern on. What does this mean? Let's use Future Drone as an example:

Figure 6.7: ControllerFacade

As you can see, ControllerFacade is an implementation of the DroneController API, and it delegates calls to other controller managers. This is a violation of the ISP.

However, if we apply the façade design pattern to the flight subsystem, which is responsible for controlling the flying ability of the drone, then this is not a violation of the ISP, as shown in the following diagram:

Figure 6.8: Facade of the flight controller subsystem

As you can see, FlyControllerManager, which is a façade, implements the FlyController interface, which has four methods to control the drone, and it delegates calls to other classes inside the flight subsystem. In this way, the client, FlyRemoteControlDevice, doesn't need to know the internal details of the flight subsystem. All it has to do is interact with a simple unified interface, FlyControllerManager. In this design, the client isn't forced to depend on methods that it doesn't need. Therefore, the façade design pattern used in this design doesn't violate the ISP.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.71.115