面向對象原則之接口隔離原則

接口隔離原則

基本介紹

接口隔離原則(Interface Segregation Principle, ISP),意爲使用多個專門的接口,而不使用單一的總接口,即客戶端不應該依賴那些它不需要的接口。

根據接口隔離原則,當一個接口太大時,我們需要將它分割成一些更細小的接口,使用該接口的客戶端僅需知道與之相關的方法即可。每一個接口應該承擔一種相對獨立的角色,不幹不該乾的事,該乾的事都要幹。這裏的“接口”往往有兩種不同的含義:一種是指一個類型所具有的方法特徵的集合,僅僅是一種邏輯上的抽象;另外一種是指某種語言具體的“接口”定義,有嚴格的定義和結構,比如Java語言中的interface。對於這兩種不同的含義,接口隔離原則的表達方式以及含義都有所不同:

  1. 當把“接口”理解成一個類型所提供的所有方法特徵的集合的時候,這就是一種邏輯上的概念,接口的劃分將直接帶來類型的劃分。可以把接口理解成角色,一個接口只能代表一個角色,每個角色都有它特定的一個接口,此時,這個原則可以叫做“角色隔離原則”。
  2. 如果把“接口”理解成狹義的特定語言的接口,那麼接口隔離原則表達的意思是指接口僅僅提供客戶端需要的行爲,客戶端不需要的行爲則隱藏起來,應當爲客戶端提供儘可能小的單獨的接口,而不要提供大的總接口。在面向對象編程語言中,實現一個接口就需要實現該接口中定義的所有方法,因此大的總接口使用起來不一定很方便,爲了使接口的職責單一,需要將大接口中的方法根據其職責不同分別放在不同的小接口中,以確保每個接口使用起來都較爲方便,並都承擔某一單一角色。接口應該儘量細化,同時接口中的方法應該儘量少,每個接口中只包含一個客戶端(如子模塊或業務邏輯類)所需的方法即可,這種機制也稱爲“定製服務”,即爲不同的客戶端提供寬窄不同的接口。

代碼示例

下面我們一個例子來加深對接口隔離原則的理解:

public interface IBehavior {

    void eat(); // 喫
    void go(); // 走
    void run(); // 跑
    void flay(); // 飛
}
public class Dog implements IBehavior {
    @Override
    public void eat() {
        System.out.println("狗在喫東西");
    }

    @Override
    public void go() {
        System.out.println("狗在走路");
    }

    @Override
    public void run() {
        System.out.println("狗在跑");
    }

    @Override
    public void flay() {

    }
}
public class Snake implements IBehavior {
    @Override
    public void eat() {
        System.out.println("蛇會喫東西");
    }

    @Override
    public void go() {

    }

    @Override
    public void run() {

    }

    @Override
    public void flay() {

    }
}
public class Bird implements IBehavior {
    @Override
    public void eat() {
        System.out.println("鳥會喫東西");
    }

    @Override
    public void go() {
    }

    @Override
    public void run() {

    }

    @Override
    public void flay() {
        System.out.println("鳥會飛");
    }
}

上述代碼中有一個IBehavior接口,有eatgorunflay四個方法,分別用來描述動物的行爲,此接口擁有三個實現類,分別是DogSnakeBird,代表狗、蛇、鳥三種動物,但是並非所有動物都擁有這四個行爲,有一些行爲是不需要,因此此接口違背了接口隔離原則,下面我們來進行重構:

public interface IBehaviorEat {

    void eat(); // 喫
}

public interface IBehaviorFly {
    void flay(); // 飛
}
public interface IBehaviorGo {

    void go(); // 走
    void run(); // 跑
}
public class Dog implements IBehaviorEat,IBehaviorGo {
    @Override
    public void eat() {
        System.out.println("狗在喫東西");
    }

    @Override
    public void go() {
        System.out.println("狗在走路");
    }

    @Override
    public void run() {
        System.out.println("狗在跑");
    }
}
public class Snake implements IBehaviorEat {
    @Override
    public void eat() {
        System.out.println("蛇會喫東西");
    }
}

public class Bird implements IBehaviorEat, IBehaviorFly {
    @Override
    public void eat() {
        System.out.println("鳥會喫東西");
    }

    @Override
    public void flay() {
        System.out.println("鳥會飛");
    }
}

我們對動物的行爲進行了歸類,抽象到不同的接口上,不同的動物可以單獨去實現這些行爲,也就避免了去實現多餘行爲的問題,滿足了接口隔離原則的要求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章