介面隔離原則 Interface Segregation Principle (ISP)

Finn
Finn
Jun 4, 2018 · 5 min read

不應該強迫用戶去依賴他們未使用的方法

最小化類別與類別之間的介面

這外表看起來有點胖...

概述

介面過肥胖會讓使用的人有不正常的耦合關係,這種關係會使需要經常變更需求的敏捷開發會容易產生Bug,所以要盡量依照用戶功能來縮小或客制

你是否有遇到?

  • 繼承後空實作
  • 介面過多
  • 並非全部方法使用到

沒有遵守的話會?

可以分兩種情況

  1. 繼承或抽象類別:多餘的介面在子類別可能會有空實作會對使用方照成“不可預期的錯誤”
  2. Compile:未使用方法的變更”而帶來的變更,假設A類別有BCD方法,E用了B其他人用了C或D,假設為了E改變了B介面,這樣導致C跟D的使用者全部要重新Compile

解決方法

  • 客製化介面 : 客制用戶的Interface,只提供用到的,再利用組合實作
  • 分割組合:將類別分割後,需要reuse實作地方在利用組合方式實現,這裡可以使用多重繼承或Delegate等等

違反單一責任原則SRP?

在分割的過程中當然不能違反SRP,只不過SRP是以開發角度去設計的,注重的是職責,然而ISP是以用戶端角度去分割的,注重的是對介面的依賴隔離,就我認為當模組遵守SRP後依照用戶需求再去分離客製與抽象介面,進而設計框架


範例

以書中ATM提款機為範例,依據操作功能來對應不同的UI,然而ATM的UI有很多像是語音、盲人點字板、文字等等

目前有三個功能與對應的UI

  • 存款 Deposit Transaction

提示輸入存款金額 ( requestDepositAmount)

  • 提款 Withdrawal Transaction

提示輸入提款金額(requestWithdrawalAmount)

提示餘額不足(informInsufficientFunds)

  • 轉帳 Transfer Transaction

提示轉帳金額(requestTransferAmount)

根據DIP 高階模組不應該依賴低階模組,而是依賴抽象

先將ATM的UI所需要的方法用抽象方法建立,然後在用各個UI去實作

下面的範例是實作ScreenUI

也可以用繼承方法達到同樣效果,但這樣明顯違反LSP

接下來要實作ATM功能部分

根據開放封閉原則OCP,利用抽象介面,來讓每個類別實作抽象方法execute,所以我們寫一個Transaction抽象類別,有execute方法,每個交易都必須要實作execute,再根據交易不同而實作不同的execute

這樣寫目前看起來沒有什麼問題,不過對各個功能來說,ATM UI提供了多餘不需要的介面

例如現在要寫無卡提款介面,只需要提款介面,這樣就依賴到不需要用的方法,其他介面就會有空實作或拋出Exception,也意味著違反了里式替換原則LSP

再來今天因為提款需求改動,可能要多帶一個參數,所以修改了提款方法介面,會讓其他匯款與轉帳等等用到的人需要重新Compile,這樣就是違反了介面隔離原則ISP


要解決這個問題,可以將ATMUI的抽象方法,在單一責任原則SRP的前提下根據用戶功能來將責任分離,最後可以用協定繼承再將他合成

利用多重繼承或協定繼承可以將ATM UI合併起來

ScreenUI Extensions ATMUI,也可以分別對需要功能的UI做實作(Deposit UI, Withdrawal UI, Transfer UI)

在 Transaction 功能上帶入Protocol的UI,這樣在execute時用戶只會顯示他能使用的方法(最小介面)

以使用者角度來分開介面,就不會有前面的空實作與Compile的問題


總結

在越龐大的專案上,介面肥大依賴太多的檔案,會照成Compile的速度飛快成長,一部分可以思考是否違反單一責任原則SRP,將責任以外的拆出來,再來思考使用者是否有依賴到不要的介面

利用介面分離來達到功能分離,也就是解耦合,應該將肥胖介面分解成以使用者為主的介面,隱藏不必要的介面,不應該服務多個使用者

我們都知道顆粒越小會更有靈活度,但也同時可能造成不必要的複雜性,這種情況就要靠經驗去累積判斷


Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade