设计模式六大原则4—接口隔离原则

接口隔离原则
定义:
1)客户端不该依赖它不需要的接口;
2)类间的依赖关系应该建立在最小的接口上。

问题由来:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类C来说不是最小接口,则类B和类D必须去实现他们不需要的方法,如下图所示。


解决方案:将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。

举例来说明接口隔离原则:

       使用Manager类代表一个管理工人的管理者。有两种类型的工人:普通的和高效的,这两种工人都需要吃午饭。现在来了一批机器人,它们同样为公司工作,但是他们不需要吃午饭。一方面Robot类需要实现IWoker接口,因为他们要工作;另一方面,它们又不需要实现IWorker接口,因为它们不需要吃饭。在这种情况下IWorker就被认为是一个被污染了的接口。

    1. // interface segregation principle - bad example  
    2.   
    3. interface IWorker {  
    4.     public void work();  
    5.   
    6.     public void eat();  
    7. }  
    8.   
    9. class Worker implements IWorker {  
    10.     public void work() {   
    11.         // ....working  
    12.     }  
    13.   
    14.     public void eat() {   
    15.         // ...... eating in launch break  
    16.     }  
    17. }  
    18.   
    19. class SuperWorker implements IWorker{     
    20.     public void work() {          
    21.         //.... working much more      
    22.     }     
    23.       
    24.     public void eat() {       
    25.         //.... eating in launch break     
    26.     }  
    27. }  
    28.           
    29. class Manager {   
    30.     IWorker worker;   
    31.       
    32.     public void setWorker(IWorker w) {   
    33.         worker=w;  
    34.     }   
    35.       
    36.     public void manage() {  
    37.         worker.work();   
    38.     }  
    39. }

    依据接口隔离的原则,我们应该把IWorker接口划分为两个独立的接口,如下面的代码所示。

  1. //interface segregation principle - good example  
  2.   
  3. interface IWorkable {     
  4.     public void work();  
  5. }  
  6.   
  7. interface IFeedable{  
  8.     public void eat();  
  9. }  
  10.   
  11. class Worker implements IWorkable, IFeedable {    
  12.     public void work() {          
  13.         // ....working    
  14.     }     
  15.       
  16.     public void eat() {       
  17.         //.... eating in launch break     
  18.     }  
  19. }  
  20.   
  21. class SuperWorker implements IWorkable, IFeedable{    
  22.     public void work() {          
  23.         //.... working much more      
  24.     }     
  25.       
  26.     public void eat() {       
  27.         //.... eating in launch break     
  28.     }  
  29. }  
  30.   
  31. class Robot implements IWorkable{     
  32.     public void work() {          
  33.     // ....working    
  34.     }  
  35. }  
  36.   
  37. class Manager {  
  38.     IWorkable worker;  
  39.   
  40.     public void setWorker(IWorkable w) {  
  41.         worker = w;  
  42.     }  
  43.   
  44.     public void manage() {  
  45.         worker.work();  
  46.     }  
  47. }  

 这样使用接口隔离原则可以防止庞大、臃肿的接口,这也就接口隔离原则的目的所在。

      接口隔离尽量使用多个专门的接口,这和单一职责原则很类似。其实不然,其一,单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。其二,单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;而接口隔离原则主要约束接口接口,主要针对抽象,针对程序整体框架的构建。

     在依据接口隔离原则拆分接口时,首先必须满足单一职责原则。其次,在使用接口隔离原则时,应做到以下几点:

  • 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
  • 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。                                                                       那么,在实际应用中,通常一个接口只服务于一个子模块或是业务逻辑;
  • 力求通过业务逻辑压缩接口中的“public”方法,让接口“满身筋骨”。
  • 已被污染的接口,尽量去修改;若变更太大的话,可以使用适配器模块。


你可能感兴趣的:(设计模式)