接口隔離原則:精簡接口福澡,專注職責(zé),多環(huán)境配置管理案例

image.png

接口隔離原則(Interface Segregation Principle, ISP)是SOLID設(shè)計原則中的第四個原則驹马。它主張不應(yīng)該強迫客戶依賴于它們不使用的方法革砸,即一個類對另一個類的依賴應(yīng)該建立在最小的接口上。

肖哥彈架構(gòu) 跟大家“彈彈” 代碼設(shè)計技巧糯累,需要代碼關(guān)注

歡迎 點贊算利,點贊,點贊泳姐。

關(guān)注公號Solomon肖哥彈架構(gòu)獲取更多精彩內(nèi)容

歷史熱點文章

2. 接口隔離設(shè)計圖:

將一個臃腫的接口拆分為多個客戶端特定的接口:

image.png

3. 接口隔離解決什么:

接口隔離原則解決了因為接口設(shè)計過于龐大而導(dǎo)致的低內(nèi)聚和高耦合問題效拭,使得使用接口的類實現(xiàn)了許多它們不需要的方法。

4. 接口隔離特點:

  • 接口細(xì)分:接口應(yīng)該盡可能小且職責(zé)單一胖秒。
  • 客戶端定制:接口應(yīng)該根據(jù)客戶端的需要定制缎患。
  • 高內(nèi)聚:每個接口都聚焦于特定的功能。
  • 低耦合:客戶端只依賴于它們需要的接口阎肝。

5. 接口隔離缺點:

  • 接口數(shù)量增加:可能會導(dǎo)致接口數(shù)量過多挤渔,管理起來較為復(fù)雜。
  • 設(shè)計難度:需要更多的設(shè)計思考來確定合適的接口粒度风题。

6. 接口隔離使用場景:

當(dāng)一個類實現(xiàn)了許多它不需要的方法時判导,或者當(dāng)多個類因為依賴同一個接口而互相影響時,應(yīng)該考慮使用接口隔離原則俯邓。

7.接口隔離案例

7.1 多環(huán)境配置管理案例

考慮一個應(yīng)用骡楼,它需要根據(jù)不同的環(huán)境(開發(fā)熔号、測試稽鞭、生產(chǎn))加載不同的配置。

重構(gòu)前:

    public interface IEnvironmentConfig {
        String getDatabaseUrl();
        String getAuthServiceUrl();
        String getEmailServiceUrl();
    }

    public class DevEnvironmentConfig implements IEnvironmentConfig {
        @Override
        public String getDatabaseUrl() {
            return "dev_database_url";
        }

        @Override
        public String getAuthServiceUrl() {
            // Dev環(huán)境可能不需要認(rèn)證服務(wù)
            return "";
        }

        @Override
        public String getEmailServiceUrl() {
            return "dev_email_service_url";
        }
    }

    // Prod環(huán)境的配置類...

重構(gòu)后:

    public interface IDatabaseConfig {
        String getDatabaseUrl();
    }

    public interface IAuthServiceConfig {
        String getAuthServiceUrl();
    }

    public interface IEmailServiceConfig {
        String getEmailServiceUrl();
    }

    public class DevEnvironmentConfig implements IDatabaseConfig, IEmailServiceConfig {
        @Override
        public String getDatabaseUrl() {
            return "dev_database_url";
        }

        // DevEnvironmentConfig不實現(xiàn)IAuthServiceConfig引镊,因為它不需要認(rèn)證服務(wù)
    }

    public class ProdEnvironmentConfig implements IDatabaseConfig, IAuthServiceConfig, IEmailServiceConfig {
        @Override
        public String getDatabaseUrl() {
            return "prod_database_url";
        }

        @Override
        public String getAuthServiceUrl() {
            return "prod_auth_service_url";
        }

        @Override
        public String getEmailServiceUrl() {
            return "prod_email_service_url";
        }
    }

    public class Application {
        private IDatabaseConfig databaseConfig;
        private IAuthServiceConfig authServiceConfig;
        private IEmailServiceConfig emailServiceConfig;

        public Application(IEnvironmentConfig environmentConfig) {
            this.databaseConfig = environmentConfig;
            // 根據(jù)環(huán)境需求注入其他配置...
        }

        public void configureServices() {
            // 使用注入的配置初始化服務(wù)
        }
    }

7.2 支付系統(tǒng)集成案例

商務(wù)平臺朦蕴,需要集成多種支付方式篮条,如信用卡支付和銀行轉(zhuǎn)賬

重構(gòu)前:


public interface IPayable {
    void processPayment();
}

public class PaymentService {
    public void processPayment(IPayable payment) {
        payment.processPayment();
    }
}

// 特定支付方式實現(xiàn)IPayable接口
public class CreditCardPayment implements IPayable {
    @Override
    public void processPayment() {
        // 處理信用卡支付邏輯
    }
}

public class BankTransferPayment implements IPayable {
    @Override
    public void processPayment() {
        // 處理銀行轉(zhuǎn)賬邏輯
    }
}

分析問題:

  1. 過度依賴: IPayable 接口強制所有實現(xiàn)類都實現(xiàn) processPayment 方法,但不同支付方式可能需要不同的處理邏輯和附加步驟吩抓,例如信用卡授權(quán)或賬戶驗證涉茧。
  2. 低內(nèi)聚性: IPayable 接口可能包含了與支付處理無直接關(guān)聯(lián)的方法,導(dǎo)致接口的內(nèi)聚性降低疹娶。
  3. 擴展性差: 當(dāng)需要添加新的支付方式或改變現(xiàn)有支付邏輯時伴栓,可能需要修改接口定義或?qū)Χ鄠€類進行更改,這增加了擴展的難度雨饺。
  4. 違反LSP: 如果子類重寫了基類的方法以添加特定邏輯钳垮,這可能會影響使用基類引用的客戶端代碼,違反了里氏替換原則额港。
  5. 代碼冗余: 為了滿足接口定義饺窿,某些類可能不得不提供空實現(xiàn)或不相關(guān)的實現(xiàn),導(dǎo)致代碼冗余移斩。

重構(gòu)后:


public interface IPaymentProcessor {
    void processPayment();
}

public interface ICreditCardPaymentProcessor extends IPaymentProcessor {
    void authorizeCard();
}

public interface IBankTransferPaymentProcessor extends IPaymentProcessor {
    void validateAccount();
}

public class CreditCardPaymentProcessor implements ICreditCardPaymentProcessor {
    @Override
    public void processPayment() {
        // 處理信用卡支付邏輯
    }
    
    @Override
    public void authorizeCard() {
        // 授權(quán)信用卡
    }
}

public class BankTransferPaymentProcessor implements IBankTransferPaymentProcessor {
    @Override
    public void processPayment() {
        // 處理銀行轉(zhuǎn)賬邏輯
    }
    
    @Override
    public void validateAccount() {
        // 驗證賬戶信息
    }
}

public class PaymentService {
    public void processPayment(IPaymentProcessor paymentProcessor) {
        paymentProcessor.processPayment();
    }
}

解決的問題:

  1. 職責(zé)明確: 通過將 IPayable 拆分為 IPaymentProcessor肚医、ICreditCardPaymentProcessorIBankTransferPaymentProcessor,每個接口都聚焦于特定的支付處理職責(zé)向瓷,提高了內(nèi)聚性肠套。
  2. 更好的擴展性: 新的支付方式可以通過實現(xiàn)相應(yīng)的接口輕松添加,而不影響現(xiàn)有代碼猖任。例如糠排,如果需要添加微信支付,可以創(chuàng)建一個實現(xiàn) IPaymentProcessorWeChatPaymentProcessor 類超升。
  3. 遵循LSP: 子類(特定支付處理器)現(xiàn)在可以安全地替換基類(IPaymentProcessor)入宦,而不改變客戶端代碼的行為,因為它們提供了與基類相同的方法室琢。
  4. 減少代碼冗余: 每個支付處理器類只需要實現(xiàn)與其職責(zé)相關(guān)的接口方法乾闰,消除了不必要的空實現(xiàn)或不相關(guān)的方法。
  5. 靈活性增強: 通過分離接口盈滴,可以更靈活地組合不同的支付處理步驟涯肩,例如,可以在信用卡支付處理器中添加額外的授權(quán)步驟巢钓,而不會影響到其他支付方式病苗。
  6. 易于維護: 當(dāng)需要修改特定支付方式的邏輯時,只需修改對應(yīng)的接口實現(xiàn)症汹,而不會影響到其他支付方式的實現(xiàn)硫朦,簡化了維護工作。

8. 參考開源框架:

  • 在Java的Spring框架中背镇,接口通常被設(shè)計得非常小且職責(zé)單一咬展,以確保它們可以被客戶端類輕松實現(xiàn)泽裳,而不會引入不必要的依賴。
  • 在Spring框架中破婆,通過使用Profile來區(qū)分不同環(huán)境的配置涮总,體現(xiàn)了接口隔離原則。

9. 總結(jié):

接口隔離原則是提高軟件系統(tǒng)可維護性和靈活性的關(guān)鍵原則祷舀。通過將大型接口拆分為更小的瀑梗、特定于客戶端的接口,我們減少了客戶端類與它們不使用的接口方法之間的不必要耦合裳扯。雖然這可能會導(dǎo)致接口數(shù)量的增加夺克,但它為構(gòu)建一個更加模塊化和可擴展的系統(tǒng)提供了堅實的基礎(chǔ)。遵循接口隔離原則有助于確保每個接口都緊湊且職責(zé)明確嚎朽,從而簡化了代碼的理解和維護铺纽。

歷史熱點文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哟忍,隨后出現(xiàn)的幾起案子狡门,更是在濱河造成了極大的恐慌,老刑警劉巖锅很,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件其馏,死亡現(xiàn)場離奇詭異,居然都是意外死亡爆安,警方通過查閱死者的電腦和手機叛复,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扔仓,“玉大人褐奥,你說我怎么就攤上這事∏檀兀” “怎么了撬码?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長版保。 經(jīng)常有香客問我呜笑,道長,這世上最難降的妖魔是什么彻犁? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任叫胁,我火速辦了婚禮,結(jié)果婚禮上汞幢,老公的妹妹穿的比我還像新娘驼鹅。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布谤民。 她就那樣靜靜地躺著,像睡著了一般疾宏。 火紅的嫁衣襯著肌膚如雪张足。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天坎藐,我揣著相機與錄音为牍,去河邊找鬼。 笑死岩馍,一個胖子當(dāng)著我的面吹牛碉咆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛀恩,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼疫铜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了双谆?” 一聲冷哼從身側(cè)響起壳咕,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎顽馋,沒想到半個月后谓厘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡寸谜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年竟稳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熊痴。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡他爸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出果善,到底是詐尸還是另有隱情讲逛,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布岭埠,位于F島的核電站盏混,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏惜论。R本人自食惡果不足惜许赃,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望馆类。 院中可真熱鬧混聊,春花似錦、人聲如沸乾巧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咳胃,卻和暖如春植康,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背展懈。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工销睁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人存崖。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓冻记,卻偏偏與公主長得像,于是被迫代替她去往敵國和親来惧。 傳聞我的和親對象是個殘疾皇子冗栗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容