本章用来叙述设计模式中的接口隔离原则。叙述方式同样采用实例演示的方式。
一、基本介绍 接口隔离原则的核心:客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。
二、实例介绍 我们现在设计一个接口,接口中有5个功能,分别让B,D类实现这个接口;然后,我们再设计A,C类,其中A,C类分别依赖B,D类;A使用B类中的option1,option2,option3方法;C使用D类中option1,option4,option5方法。
将以上的情景展示成代码,就是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 COPY interface Interface1 { void option1 () ; void option2 () ; void option3 () ; void option4 () ; void option5 () ; } class B implements Interface1 { @Override public void option1 () { System.out.println("B...o1" ); } @Override public void option2 () { System.out.println("B...o2" ); } @Override public void option3 () { System.out.println("B...o3" ); } @Override public void option4 () { System.out.println("B...o4" ); } @Override public void option5 () { System.out.println("B...o5" ); } } class D implements Interface1 { @Override public void option1 () { System.out.println("A...o1" ); } @Override public void option2 () { System.out.println("A...o1" ); } @Override public void option3 () { System.out.println("A...o1" ); } @Override public void option4 () { System.out.println("A...o1" ); } @Override public void option5 () { System.out.println("A...o1" ); } } class A { public void depend1 (Interface1 interface1) { interface1.option1(); } public void depend2 (Interface1 interface1) { interface1.option2(); } public void depend3 (Interface1 interface1) { interface1.option3(); } } class C { public void depend1 (Interface1 interface1) { interface1.option1(); } public void depend4 (Interface1 interface1) { interface1.option4(); } public void depend5 (Interface1 interface1) { interface1.option5(); } }
从上面的代码中,我们可以看到类A只用到了接口中的1,2,3方法,但是上面的接口实现,却全部实现了;同样C类只使用了1,4,5方法,而依赖的D也实现了接口的全部方法。
现在将以上的类和接口呈现出UML图展示:
通过上面的图可以看到,
类 A 通过接口 Interface1 依赖类 B,类 C 通过接口 Interface1 依赖类 D,如果接口 Interface1 对于类 A 和类 C来说不是最小接口,那么类 B 和类 D 必须去实现他们不需要的方法。其中B必须去实现4,5方法;D必须去实现2,3方法。
三、接口隔离原则 按照接口隔离原则应当这样处理:
将接口 Interface1 拆分为独立的几个接口(这里我们拆分成3个接口),类 A 和类 C 分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。将A,C公共使用的接口方法抽象成一个接口,各自不相交的部分再抽象各自成一个接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 COPY interface Interface1 { void option1 () ; } interface Interface2 { void option2 () ; void option3 () ; } interface Interface3 { void option4 () ; void option5 () ; } class B implements Interface1 , Interface2 { @Override public void option1 () { System.out.println("A...o1" ); } @Override public void option2 () { System.out.println("A...o2" ); } @Override public void option3 () { System.out.println("A...o3" ); } } class D implements Interface1 , Interface3 { @Override public void option1 () { System.out.println("B...o1" ); } @Override public void option4 () { System.out.println("B...o4" ); } @Override public void option5 () { System.out.println("B...o5" ); } } class A { public void depend1 (Interface1 interface1) { interface1.option1(); } public void depend2 (Interface2 interface2) { interface2.option2(); } public void depend3 (Interface2 interface2) { interface2.option3(); } } class C { public void depend1 (Interface1 interface1) { interface1.option1(); } public void depend4 (Interface3 interface3) { interface3.option4(); } public void depend5 (Interface3 interface3) { interface3.option5(); } }
其UML类图:
从类图中看出,A依赖使用到的方法只有1,2,3;C依赖使用到的方法只有1,4,5。其中A不用依赖接口2,C不用依赖接口2。
四、总结 在实例介绍代码一中,根据以上类图的改进原则:
类 A 通过接口 Interface1 依赖类 B,类 C 通过接口 Interface1 依赖类 D,如果接口 Interface1 对于类 A 和类 C来说不是最小接口,那么类 B 和类 D 必须去实现他们不需要的方法。
将接口 Interface1 拆分为独立的几个接口,类 A 和类 C 分别 与他们需要的接口建立依赖关系。也就是采用接口隔离原则。
接口 Interface1 中出现的方法,根据实际情况拆分为三个接口。
Volantis Edition (based on 1.3.10)