介面的所有權之爭

2022-06-23 18:02:25

 在 一文get到SOLID原則的重點 和 SOLDI原則之DIP:依賴倒置原則 裡提到過DIP (依賴倒置原則)裡提到過介面所有權的問題。今天再次聊下介面所有權。

在《敏捷軟體開發:原則、模式與實踐》裡作者提到了一個開關和檯燈設計的例子。

圖片

圖1

 

圖1的設計中,Switch 物件可以輪詢真實的開關的狀態 ,並且可以傳送相應的turnOn 和turnOff 訊息給Light。這個設計不好在哪裡? 它違反了依賴倒置原則(DIP)和開放封閉原則(OCP)。對DIP違反比較明顯,Switch 依賴了具體的類,DIP 要依賴於抽象類。對於OCP 的違反不明顯,但切中要害。不能容易的擴充套件Switch 去管理除Light外的其他物件。

作者提出了簡單的設計模式Abstract Server模式,如圖2。模式也許沒有聽過,但一定這樣用過。我們在Switch 和Light 之間引入一個介面,這樣就使得Switch 能夠控制任何實現了這個介面的東西。這就滿足了DIP和OCP。

圖片

圖2

 

再來看一個例子,微軟為了展示.Net企業系統開發的能力。曾經發布過一個PetShop作為範例,後來很多企業系統的架構都採用了參照了或簡化了此架構設計。標準的三層架構。

圖片

從上圖所知,業務層對資料存取層抽象出來的IDAL模組。除了解除了向下的依賴之外,對於其上的業務邏輯層,相同僅存在弱依賴關係。那麼來看這個設計滿足了DIP:依賴倒置原則的高層模組不應該依賴於低層模組,二者都應該依賴於抽象。那麼IDAL介面層的所有權屬於誰的?以前一直有這個疑問直到看到這一章疑問解決了。通常認為IDAL介面層屬於DAl層,那是不對的。這裡的IDAL介面的所有權是屬於BLL層了

關於介面所有權的描述,作者說到在20世紀初,我們通常認為實體關係支配著一切。有很多名著都建議把繼承層次結構一起放到一個包中。似乎是合理的,繼承是非常強的實體關係。但在最近10年中(這本書中文版是2003年出的),我們認識到繼承的實體強度是一個誤導,並且繼承層次結構通常也不應該被打包在一起,相反,往往客戶和它們控制的介面打包在一起。換言之客戶和介面之間的邏輯關係要強於介面和它的派生類之間的邏輯繫結關係。介面屬於它的客戶,而不是它的派生類。

這裡的介面有的人也稱為SPI ,不同一行業標準的SPI,意思是系統內部的標準介面,內部都依賴於這個SPI,用這種模式可實現系統對外部系統的隔離,解耦外部的系統。如果SPI可以做為上下游的介面標準,那麼可以由它們來實現。如果做不到,這個SPI 由系統內部自己去實現,只有實現是依賴到三方介面的,這樣如果三方介面有替換,我們可以用新的實現去擴充套件就好了。

結論:

介面所有權屬於它的客戶,這裡的所有權指邏輯關係和打包和釋出。由客戶模組或者層來宣告它們所需要的服務介面,那麼僅當客戶需要時才會對介面改變。這樣改變實現抽象介面的類就不會影響到客戶。完全做到實現是可延伸,可替換。

相關閱讀:

策略模式在應用中的實踐

一文get到SOLID原則的重點

微服務設計的一些原則和需要考慮的一些事