接口隔离原则(The Interface-Segregation Principle)强调类的功能要单一,类的功能臃肿增加不必要的耦合,增加代码的脆弱性,还会增加编译依赖。该原则建议将方法分组,达到隔离接口的目的,具体的方法有委托和多重继承。

在Timed Door的例子中,开始的实现是Timed Door继承Door,Door实现Timer Client这个接口,这样Timed Door就可以通过Timer Client这个接口去使用Timer的功能。但这样做会导致Door依赖于Timer Client,而且并不是所有的Door都需要定时功能。所有的继承于Door的子类都需要提供退化的Timeout方法,违反了LSP

注意,这里的TimerClient是Timer实现的需求,与Door无关。所有使用Timer的类对相当于Timer的client,需要实现TimerClient这个接口,用于Timer time out时调用。

敏捷开发原则与实践(七)之接口隔离原则

Timer Client at Top of Hierarchy

Door和Timer Client中的接口分别由不同的client使用,既然使用者相互独立,接口也应该独立,因为使用者也会对接口产生影响。我们一般都会考虑接口对使用者的影响,但使用者也会对接口提出更多的要求。比如文中由于door的需求,需要Timer提供带timeOutId的注册接口。但这个接口的变化会导致Door的所有子类代码都需要修改,这个设计的确很糟糕。

接口隔离原则:使用者不应该被逼去依赖它们不使用的方法。

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

通过委托或多重继承可以避免依赖不使用的方法。一般使用多重继承,因为委托会产生多余的性能和空间的耗用。这里的委托就是说将对TimerClient的实现委托给TimerClientAdapter去做。

TimedDoor例子中通过将定时接口和Door接口隔离,避免了其它Door子类依赖于定时接口。

 敏捷开发原则与实践(七)之接口隔离原则

Multiply inherited Timed Door

 

敏捷开发原则与实践(七)之接口隔离原则

Door Timer Adapter

 1 public interface TimerClient {
 2     public void timeOut();
 3 }
 4 
 5 public class Timer2 extends TimerTask{
 6 
 7     private TimerClient mTc;
 8     private Timer mTimer;
 9     
10     public void registry(int timeout, TimerClient tc) {
11         mTc = tc;
12         mTimer = new Timer();
13         mTimer.schedule(this, timeout*1000);
14     }
15 
16     @Override
17     public void run() {
18         // TODO Auto-generated method stub
19         mTc.timeOut();
20     }
21 }
Timer以及接口

相关文章: