java架構模式與設計模式(一)--六邊形架構

本文來自

前言

注: 當我在學習DDD時,看到其中的六邊架構,在初步瞭解其架構思想之後,就深深地被吸引了,因爲它可以解決諸多我在項目中遇到的問題。

這裏將着重介紹六邊形架構的思想,以及其解決的問題,並不與其它架構做深入的對比。

六邊形架構 又被稱之爲ports&adpers(我認爲這個名稱更合適),是 Cockburn在2005年提出的,目的是爲了解決業務邏輯與輸入輸出的解耦。

架構思想

想像一下電腦如何與周邊設備如何交互的:

周邊設備有耳機、鍵盤、外接顯示器、耳機等,它們通過電腦的USB、HDMI等端口進行連接;但有時剛買來一個新的設備(比如打印機),想通過USB與電腦連接,但你插上時,電腦卻提示你無法識別,需要安裝驅動,你按照說明,安裝好驅動就可以使用了。而且比較神奇的是,我有兩個鼠標,一個是ps/2接口,一個是USB接口,但插上去都可以用, 這是因爲系統中安裝了兩種接口類型的驅動(適配器)。

通過上面的描述,我們知道,電腦與周邊設備是通過端口與驅動(適配器)交互的,且只需要有相應的驅動,端口可以和不同的設備進行交互。

我們在設計架構和編碼過程中經常犯一個錯誤,將業務邏輯與外部實體間的交互糾纏在一起。比如,在分層架構中,對數據庫的訪問和外部接口的訪問通常放在gateway中,而由於分層構架,只做了業務的職現劃分,並未做層次的解耦,造成對於外部的訪問成了業務邏輯的內核;同樣,對於對外提供的接口,封裝在controller中,也是同樣的道理。(當然,這裏並不是說分層架構不好,只是處理問題的角度不同)。

六邊形架構關注的是“外部”和“內部”的差別,內部業務邏輯(Application)與外設(APP,WEB,數據庫等)完全隔離,僅通過Adapter 進行交互。

 

那Adapter起什麼作用呢?它負責將與外設交互的數據(包括命令、query)轉化爲Application可以理解的信息(業務module),並通過內部系統提供的接口進行業務邏輯的處理。

說了那麼多adpter,那port該如何界定其職責呢? 我們知道,電腦上端口定義了設備的通信協議,只要是相同的端口,無論是什麼設備必須遵循這個協議,只是其通信的內容可能有所不同。對於軟件系統來講,port上端口協議的體現就是api,即業務系統對外暴露的接口,一個端口可以有多個適配器。比如一個系統提供產口的信息的展示,這時候該信息可能需要在app,web或者作爲遠程服務對外提供產品信息,這時候由Application是提供一個query 接口,並返回一個Product對象,至於要將其轉換成app,web或者遠程服務json格式,則由adapter來完成。

爲什麼它叫六邊形架構呢?六邊形的一個邊就代表一個端口,但並不代表一個六邊型架構就必須有6個端口,其實這和六個邊沒有任何關係,作者只是爲了方便表達自己的思想,將架構畫成了六邊形,也方便使用者能夠在業務架構時,更方便的設計。

這裏還是提醒一下,雖然六邊形強調內部和外部的區別,但並不代表我們不關注外部接口的主被動(對外提供服務,還是調用外部服務),但我們可以在實現端口和adapters 時,通過技術來屏蔽這種差異,但卻不適合,也沒必要使用一個完全相同的端口來屏蔽這種差異。所以一般的六邊形架構架構會在左右兩端各有端口,左邊代表對外提供服務,右邊代表調用外部服務。

通過上面的介紹,相信你已經瞭解了六邊形的設計思想。那它這種業務邏輯和外部系統的分離,還給我們帶來什麼好處呢?

 

如上圖所示,應用外對提供了兩個端口,用戶側API和數據側API。用戶側API,通過四個適配器爲app,http,GUI,ie提供服務;數據側通過兩個適配器(DB和mock)爲應用提供適配服務。大家看到這裏,可能會有些吃驚,怎麼還有mock?

是的,只需要實現data-side端口的的服務都可以爲Application提供數據,對系統來說並不會感知到服務的差異,也就是說mock和db 可以提供無差異的服務。說到這裏你就明白了,再也不用將測試用例嵌入到業務邏輯中了,只要實現相應的adapter就可以了,再也不用因爲業務代碼的變動而更改測試用例。爲集成化測試提供了很大的方便。

稍後我會補充一個項目案例!!!!

http://alistair.cockburn.us/Hexagonal+architecture

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章