接口隔離原則
設計模式系列文章
1、問題由來
類A通過接口I依賴類B,類C通過接口I依賴類D,如果接口I對於類B和類D來說不是最小接口,則類B和類D必須去實現他們不需要的方法。
2、什么是接口隔離原則
接口隔離原則比較簡單,有兩種定義:
- Clients should not be forced to depend upon interfaces that they don't use.(客戶端不應該強行依賴它不需要的接口)
- The dependency of one class to another one should depend on the smallest possible interface.(類間的依賴關系應該建立在最小的接口上)
其實上述兩種定義說的是同一種意思。客戶端不應該依賴它不需要的接口,意思就是說客戶端只要依賴它需要的接口,它需要什么接口,就提供什么接口,不提供多余的接口。“類間的依賴關系應該建立在最小的接口上”也表達這一層意思。通俗的講就是:接口中的方法應該盡量少,不要使接口過於臃腫,不要有很多不相關的邏輯方法。
通過簡單的代碼還原開篇的問題,代碼如下:
public interface I { public void method1(); public void method2(); public void method3(); } public class B implements I{ @Override public void method1() { System.out.println("類B實現了接口I的方法1"); } @Override public void method2() { System.out.println("類B實現了接口I的方法2"); } @Override public void method3() {//類B並不需要接口I的方法3功能,但是由於實現接口I,所以不得不實現方法3 //在這里寫一個空方法 } } public class D implements I{ @Override public void method2() { System.out.println("類D實現了接口I的方法2"); } @Override public void method3() { System.out.println("類D實現了接口I的方法3"); } @Override public void method1() {//類D並不需要接口I的方法1功能,但是由於實現接口I,所以不得不實現方法1 //在這里寫一個空方法 } } //類A通過接口I依賴類B public class A { public void depend1(I i){ i.method1(); } } //類C通過接口I依賴類D public class C { public void depend1(I i){ i.method3(); } } public class Client { public static void main(String[] args) { A a = new A(); I i1 = new B(); a.depend1(i1); C c = new C(); I i2 = new D(); c.depend1(i2); } }
運行結果:
類B實現了接口I的方法1
類D實現了接口I的方法3
從以上代碼可以看出,如果接口過於臃腫,不同業務邏輯的抽象方法都放在一個接口內,則會造成它的實現類必須實現自己並不需要的方法,這種設計方式顯然是不妥當的。所以我們要修改上述設計方法,把接口I拆分成3個接口,使得實現類只需要實現自己需要的接口即可。只貼出修改后的接口和實現類的代碼,修改代碼如下:
public interface I1 { public void method1(); } public interface I2 { public void method2(); } public interface I3 { public void method3(); } public class B implements I1,I2{ @Override public void method1() { System.out.println("類B實現了接口I的方法1"); } @Override public void method2() { System.out.println("類B實現了接口I的方法2"); } } public class D implements I2,I3{ @Override public void method2() { System.out.println("類D實現了接口I的方法2"); } @Override public void method3() { System.out.println("類D實現了接口I的方法3"); } }
3、與單一職責原則的區別
到了這里,有些人可能覺得接口隔離原則與單一職責原則很相似,其實不然。
第一,單一職責原則注重的是職責;而接口隔離原則注重對接口依賴的隔離。
第二,單一職責原則主要是約束類,其次才是接口和方法,它針對的是程序中的實現和細節;而接口隔離原則主要約束接口,主要針對抽象,針對程序整體框架的構建。
4、注意事項
原則是前人經驗的總結,在軟件設計中具有一定的指導作用,但是不能完全照搬這些原則。對於接口隔離原則來說,接口盡量小,但是也要有限度。對接口進行細化可以提高程序設計靈活性是不爭的事實,但是如果過小,則會造成接口數量過多,使設計復雜化,所以一定要適度。