Separate Clients Mean Separate Interfaces


Door and TimerClient represent interfaces that are used by complely different clients. Timer uses TimerClient, and classes that manipulate doors use Door. Since the clients are separate, the interfaces should remain separate, too. Why? Because clients exert forces on their server interfaces.

When we think of forces that cause changes in software, we normally think about how changes to interfaces will affect their users. For example, we would be concerned about the changes to all the users of TimerClient if its interface changed. However, there is a force that operates in the other direction. Sometimes, the user forces a change to the interface.

For example, some users of Timer will register more than one timeout request. Consider the TimedDoor. When it detects that the Door has been opened, it sends the Register message to the Timer, requesting a timeout. However, before that timeout expires, the door closes, remains closed for a while, and then opens again. This causes us to register a new timeout request before the old one has expired. Finally, the first timeout request expires, and the TimeOut function of the TimedDoor is invoked. The Door alarms falsely.

We can correct this situation by using the convention shown in Listing 12-3. We include a unique timeOutId code in each timeout registration and repeat that code in the TimeOut call to the TimerClient. This allows each derivative of TimerClient to know which timeout request is being responded to.

Clearly, this change will affect all the users of TimerClient. We accept this, since the lack of the timeOutId is an oversight that needs correction. However, the design in Figure 12-1 will also cause Door, and all clients of Door, to be affected by this fix! This smells of rigidity and viscosity. Why should a bug in TimerClient have any affect on clients of Door derivatives that do not require timing? This kind of strange interdependency chills customers and managers to the bone. When a change in one part of the program affects other, completely unrelated parts of the program, the cost and repercussions of changes become unpredictable, and the risk of fallout from the change increases dramatically.

Listing 12-3. Timer with ID

public class Timer {   public void Register(int timeout,                        int timeOutId,                        TimerClient client)   {/*code*/} } public interface TimerClient {   void TimeOut(int timeOutID); }

The Interface Segregation Principle

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


When clients are forced to depend on methods they don't use, those clients are subject to changes to those methods. This results in an inadvertent coupling between all the clients. Said another way, when a client depends on a class that contains methods that the client does not use but that other clients do use, that client will be affected by the changes that those other clients force on the class. We would like to avoid such couplings where possible, and so we want to separate the interfaces.




Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net