接口隔離原則
設計模式系列文章
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、注意事項
原則是前人經驗的總結,在軟件設計中具有一定的指導作用,但是不能完全照搬這些原則。對於接口隔離原則來說,接口盡量小,但是也要有限度。對接口進行細化可以提高程序設計靈活性是不爭的事實,但是如果過小,則會造成接口數量過多,使設計復雜化,所以一定要適度。
