ISP 的核心理念非常直觀:「不應強迫客戶端(Client)依賴它不使用的方法。」
如果一個介面過於龐大(Fat Interface),包含許多不相關功能,
那麼依賴該介面的類別就會被捲入無謂變更中。
一、經典場景:胖介面的問題#
Uncle Bob 舉了一個經典例子:
假設有個巨大類別 OPS,它擁有三個方法 op1, op2, op3。
系統中有三個不同使用者(User):
User1只呼叫op1User2只呼叫op2User3只呼叫op3

Figure 10.1: The Interface Segregation Principle
違反 ISP 的後果#
如果我們讓 User1 直接依賴這個巨大 OPS 類別:
- 不必要的重新編譯: 當
User2請求修改op2時,OPS的原始碼會改變。
雖然這改變跟User1無關,但因User1依賴OPS,所以User1也須被重新編譯和部署 - 錯誤蔓延: 如果
op2的修改導致OPS發生編譯錯誤或崩潰,User1也會無法運作,即便它根本沒用到那個壞掉功能
二、解決方案:介面隔離#
解決方法是將操作隔離成特定介面:U1Ops, U2Ops, U3Ops。
User1只依賴U1Ops介面(裡面只有op1)OPS類別去實作這三個介面
這樣一來,當 op2 改變時,只有 U2Ops 和 User2 受影響,User1 則完全絕緣,不需要重新編譯。

Figure 10.2: Segregated operations
三、語言特性與架構意義#
1. 語言差異#
ISP 對於 靜態型別語言(如 Java, C++) 尤為重要,
因為這些語言原始碼的依賴(Source Code Dependency)會導致強制的重新編譯與重新部署。
對於 動態型別語言(如 Python, Ruby),這問題較不嚴重(因為依賴是在執行期推斷的),
但 ISP 仍然是良好的架構習慣。
2. 架構層次的啟示#
ISP 不僅適用於類別設計,更適用於系統架構:
- 不要依賴你不需要的: 如果系統依賴了一個龐大框架(Framework),
但只用了其中一小部分,你卻被迫引入了該框架所有依賴(Database, Libraries 等) - 攜帶包袱的風險: 這些沒用到的「包袱」可能會帶來麻煩(如安全漏洞、效能問題)

Figure 10.3: A problematic architecture
依賴一個包含「你不需要的功能」的模組是有害的。
透過 ISP,我們將龐大介面切為更小、具體的介面,確保模組間的依賴關係精確且必要。