PHP OO 物件導向原則:介面隔離原則ISP


OO_Principle_ISP

物件導向有五個原則 S.O.L.I.D. :
  • 單一職責原則 SRP (Single Responsibility Principle)
  • 開放封閉原則 OCP (Open Closed Principle)
  • 里氏替換原則 LSP (Liskov Substitution Principle)
  • 介面隔離原則 ISP (Interface Segregation Principle)
  • 依賴反轉原則 DIP (Dependency Inversion Principle)
更多物件導向的理論的學習內容會整理到 PHP OO 的進階教學:

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

到目前為止介紹:
單一職責原則講述:如何使用 actor 角色的來設計類別。
開放封閉原則講述:類別設計的原則與擴增功能的方式。
里氏替換原則講述:子類別繼承與實作介面的約束。
最後,介面隔離原則講述:商業邏輯如何與 client 用戶溝通。

一、定義與說明:

定義:
介面不應該強迫 Client 依賴於它們用不到的方法。
Clients should not be forced to depend upon interfaces that they don’t use.
類別之間的相依關係應該建立在最小的介面上
The dependency of one class to another one should depend on the smallest possible interface.
類別與類別之間的關係,應只依賴彼此需要的最少介面,介面不能太肥,應該要細化。
每一個介面(Interface)應該把不相關的方法移除,盡可能地讓方法數量降到最低。
現在的所有模組化應用程式一定會提供讓 Client 可以依賴(使用)的介面,
這些介面可能是一些實作設計模式(如 Facade 模式)的物件,也可能是真的介面(Interface)。
不過一種介面並不重要,因為這些介面的目的都是提供一個讓 Client 端可以使用我們開發模組的管道
這些介面處於應用程式與模組之間、或是專案與模組之間,這種關係就如同第三方套件提供服務 API 給一個網站使用。
對於介面來說,
模組與 Client 物件之間的溝通做好之後, Client 就是 Client ,模組並不用理會 N 個 Client 的程式長怎樣,只要 Client 能透過介面來使用我們的模組,
模組與 Client 就能順利運行。
目的:
降低商業邏輯(低階模組)與 Client 之間的耦合。
簡單講就是設計介面(interface)的時候,也應該考慮單一職責原則,把有關聯的方法放在一起,分割出多個單一功能的介面。
最後每一個介面都會是最精簡,高內聚與低耦合的介面。

範例:

如何定義一個介面讓 Client 可以使用我們的模組呢?
假設我們的低階模組有很多功能可以提供給 Client :
但是一個功能這麼多的介面,又如何供給 Client 呢?
1.製作一個巨大的 Car 或 Bus 類別來實做 Vehicle 介面的功能嗎?
2.還是使用多個小 Class 如:LightsControl, SpeedControlRadioCD 來實作 Vehicle 介面的功能,但這些小類別只提供部分有用的實作方法嗎?
很明顯兩個選項都不對,第一個違反單一職責原則,第二個違反里氏替換原則。

切割介面

我們換個方式:

把一個大介面切成多個小介面,遵守單一職責原則的前提下,替為每一個實作介面的物件的需求來客製化介面。
這可以讓小類別專注在他們要實作的介面上。實作 SpeedControl、RadioCD 介面的物件會被各種的交通工具使用,如汽車。
如上圖所示,這些交通工具依賴介面來使這些用實例化的物件。
需要的話,一個類別可以實作多個介面來取得他需要的功能。
而這些分散的介面也會迫使我們思考每個 Client 可能只需要哪些功能,進而降低與 Client 間的耦合。

結論

設計模組時,要以 Client 需求的角度建立介面,且避免設計龐多功能的單一介面。
設計介面時也要遵守單一職責原則,力求介面的功能單一化,切割出多個單一功能的介面。
而眾多的功能介面中, Client 只需要挑出幾個符合需求的介面,了解之後拼裝成對應的功能。
如果訂製了超過需求的介面,可能會迫使有些低階模組實作 Client 不需要的方法。

資源參考:


留言

這個網誌中的熱門文章

Git Commit Message 這樣寫會更好,替專案引入規範與範例

Gitlab 合併請求 Merge Request 是什麼?

PHP OO 物件導向基礎教學