設計模式心法之接口隔離原則

如需下載源碼,請訪問
https://github.com/fengchuanfang/Interface_Segregation_Principle

文章原創(chuàng),轉(zhuǎn)載請注明出處:
設計模式心法之接口隔離原則


接口隔離原則(ISP,Interface Segregation Principle)

——設計模式基本原則之一

定義:

客戶端不應該依賴它不需要的接口(Clients should not be forced to depend upon interfaces that they don't use)

類間的依賴關(guān)系應該建立在最小的接口上(The dependency of one class to another one should depend on the smallest possible interface)

接口是靜態(tài)常量和抽象方法的集合,既是其引用持有類依賴關(guān)系的協(xié)議,也是其實現(xiàn)類的規(guī)范。接口的設計在一個項目的開發(fā)中起到舉足輕重的作用,是使項目保持良好拓展性的關(guān)鍵。

接口隔離原則要求我們在設計接口時,要使用多個專門的接口不要使用單一的龐大臃腫的總接口,一個類對另一個類的依賴性應該建立在最小的接口上。要做到接口與角色一一對應,不應該讓一個接口承擔多個角色,也不應該讓一個角色由多個接口承擔。這樣設計的接口在應對未來變更時,會更具有靈活性和可拓展性。

有一工廠接口對外提供原料預處理(preProcess),半成品加工(processA1,processA2,processB1,processB2),產(chǎn)品包裝(packaging)等方法,如下:

public interface IFactory {
    String preProcess(String material);

    String processA1(String semis);
    String processA2(String semis);

    String processB1(String semis);
    String processB2(String semis);

    String packaging(String product);
}

場景類ClientA通過接口IFactory依賴類FactoryA中的preProcess,processA1,processA2,packaging方法,代碼如下:

public class ClientA {
    public static void main(String args[]) {
        IFactory factory = new FactoryA();
        String semis1 = factory.preProcess("原料");
        String semis2 = factory.processA1(semis1);
        String product = factory.processA2(semis2);
        System.out.println(factory.packaging(product));
    }
}

public class FactoryA implements IFactory {

    @Override
    public String preProcess(String material) {
        return material + "-->預處理";
    }

    @Override
    public String processA1(String semis) {
        return semis + "-->a1工序半成品加工";
    }

    @Override
    public String processA2(String semis) {
        return semis + "-->a2工序半成品加工";
    }

    @Override
    public String processB1(String semis) {
        return null;
    }

    @Override
    public String processB2(String semis) {
        return null;
    }

    @Override
    public String packaging(String product) {
        return product + "-->包裝成品";
    }

}

運行結(jié)果如下:

原料-->預處理-->a1工序半成品加工-->a2工序半成品加工-->包裝成品

場景類ClientB通過接口IFactory依賴類FactoryB中的preProcess,processB1,processB2,packaging方法,代碼如下:


public class ClientB {

    public static void main(String[] args) {
        IFactory factory = new FactoryB();
        String semis1 = factory.preProcess("原料");
        String semis2 = factory.processB1(semis1);
        String product = factory.processB2(semis2);
        System.out.println(factory.packaging(product));
    }

}

public class FactoryB implements IFactory {

    @Override
    public String preProcess(String material) {
        return material + "-->預處理";
    }

    @Override
    public String processA1(String semis) {
        return null;
    }

    @Override
    public String processA2(String semis) {
        return null;
    }

    @Override
    public String processB1(String semis) {
        return semis + "-->b1工序半成品加工";
    }

    @Override
    public String processB2(String semis) {
        return semis + "-->b2工序半成品加工";
    }

    @Override
    public String packaging(String product) {
        return product + "-->包裝成品";
    }

}

運行結(jié)果如下:

原料-->預處理-->b1工序半成品加工-->b2工序半成品加工-->包裝成品

在上述示例中,接口IFactory對于類ClientA和ClientB來說,均不是最小接口,IFactory中存在著類ClientA和ClientB使用不到的方法。但是作為IFactory的實現(xiàn)類FactoryA和FactoryB不得不去實現(xiàn)場景類中使用不到的方法。

IFactory作為場景類ClientA,ClientB依賴對應工廠類FactoryA,FactoryB之間的協(xié)議過于繁瑣,作為其子類FactoryA,FactoryB的規(guī)范過于臃腫,這種設計顯然太過于死板而不夠靈活。如果以后因需求變更過大,無論場景類ClientA還是ClientB所依賴的接口需要更改,都會導致另一個場景類所依賴的接口實現(xiàn)類去實現(xiàn)場景類中使用不到的方法來適應這種變更,

我們可以按照接口隔離原則將IFactory拆分成以下三個接口,

public interface ISubFactory {
    String preProcess(String material);

    String packaging(String product);
}


public interface IFactoryA {
    String processA1(String semis);

    String processA2(String semis);
}

public interface IFactoryB {
    String processB1(String semis);

    String processB2(String semis);
}

然后由類FactoryA實現(xiàn)接口ISubFactory和IFactoryA,代碼如下:

public class FactoryA implements ISubFactory,IFactoryA{
    @Override
    public String preProcess(String material) {
        return material + "-->預處理";
    }

    @Override
    public String processA1(String semis) {
        return semis + "-->a1工序半成品加工";
    }

    @Override
    public String processA2(String semis) {
        return semis + "-->a2工序半成品加工";
    }

    @Override
    public String packaging(String product) {
        return product + "-->包裝成品";
    }

}

場景類中代碼如下:

public class ClientA {

    public static void main(String[] args) {
        ISubFactory subFactory = new FactoryA();
        IFactoryA factory = new FactoryA();
        String semis1 = subFactory.preProcess("原料");
        String semis2 = factory.processA1(semis1);
        String product = factory.processA2(semis2);
        System.out.println(subFactory.packaging(product));
    }

}

運行結(jié)果如下:

原料-->預處理-->a1工序半成品加工-->a2工序半成品加工-->包裝成品

由類FactoryB實現(xiàn)接口ISubFactory和IFactoryB,代碼如下:


public class FactoryB implements ISubFactory, IFactoryB {

    @Override
    public String preProcess(String material) {
        return material + "-->預處理";
    }

    @Override
    public String processB1(String semis) {
        return semis + "-->b1工序半成品加工";
    }

    @Override
    public String processB2(String semis) {
        return semis + "-->b2工序半成品加工";
    }

    @Override
    public String packaging(String product) {
        return product + "-->包裝成品";
    }
}

場景類中代碼如下:

public class ClientB {
    public static void main(String[] args) {
        ISubFactory subFactory = new FactoryB();
        IFactoryB factory = new FactoryB();
        String semis1 = subFactory.preProcess("原料");
        String semis2 = factory.processB1(semis1);
        String product = factory.processB2(semis2);
        System.out.println(subFactory.packaging(product));
    }

}

運行結(jié)果如下:

原料-->預處理-->b1工序半成品加工-->b2工序半成品加工-->包裝成品

相同的運行結(jié)果下,實現(xiàn)類FactoryA和FactoryB中均不存在其場景類中使用不到的方法,如果以后因需求變化過大,更改接口IFactoryA,也不會對實現(xiàn)類FactoryB造成任何影響。這樣設計的接口在應對未來變更時,會更具有靈活性和可拓展性。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容