天天看點

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

All problems in computer science can be solved by another level of indirection .

-- David Wheeler

計算機科學中的任何問題,都可以通過加上一層邏輯層來解決。

-- David Wheeler

為什麼要分層呢?

在計算機領域,“分層” 概念無處不在。比如 web 開發時的 MVC ,網絡程式設計時的 OSI 參考模型和 TCP/IP 協定族。

但是為什麼要進行分層呢?

分層的好處

《圖解TCP/IP》:

在這一模型中,每個分層都接收它下一層所提供的特定服務,并且負責為自己的上一層提供特定的服務。上下層之間進行互動時所遵循的約定叫做“接口”。

而Marting Fowler《企業應用架構模式》開篇第 1 章是這樣說的:

在分解複雜的軟體系統時,軟體設計者用得最多的技術之一就是分層。

在第 1 章後面,又舉了一個表現層,領域層,資料源層的例子。

Eric Evans的《領域驅動設計》(DDD):将業務語義顯現化,把原先晦澀難懂的業務算法邏輯,通過領域對象(Domain Object),統一語言(Ubiquitous Language)将領域概念清晰的顯性化表達出來。

相信我,這種表達帶來的代碼可讀性的提升,會讓接手你代碼的人對你心懷感恩的。借用Abelson的一句話是

Programs must be written for people to read, and only incidentally for machines to execute.

(是以強烈譴責那些不顧他人感受的編碼行為)

分層為什麼會帶來好處?

對于為什麼要分層,大多數文章說的隻是它帶來的好處。比如下層修改實作,不影響上層使用;分離關注點等。但是為什麼會帶來這些好處?

當用分層的觀點來考慮系統時,可以将各個子系統想像成按照“多層蛋糕”的形式來組織,每一層都依托在其下層之上。在這種組織方式下,上層使用了下層定義的各種服務,而下層對上層一無所知。另外,每一層對自己的上層隐藏其下層的細節。

Grady Booch / Robert A.Maksimchuk / Michael W.Engle / Bobbi J.Young 《面向對象分析與設計》:

開發軟體本身是一件很複雜的事情(必須認識到這一點)。而我們人類大腦的能力是有限的,不可能同時處理太多的複雜性。我們可以通過将複雜性分解、抽象、分層,一次隻需要處理一個部分複雜性,而不是所有。

是以,“分層”并不能讓複雜性消失,而是讓我們的大腦在能力範圍内處理相對重要的層面的複雜性,而忽略那些不那麼重要的細節。

比如, 開發一個HR系統,你的大腦應集中精力放在業務邏輯上,而不是作業系統如何與硬體打交道(并不是說作業系統原理不重要,隻是在HR系統上不重要)。

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

軟體開發所面對的複雜性超出了我們人類大腦一次性能處理的範圍,而分層是一種手段,幫助我們人類隻需要處理相對重要的層面的複雜性,而忽略相對不重要層面的複雜性。進而使我們以更低的成本達到目的。而好處隻是副産品。

接下來的問題,如何進行分層呢?

分層好壞的标準是什麼?

留給大家思考。

分層模式是最通用的架構,也被叫做N層架構模式(n-tier architecture pattern).這也是Java EE應用經常采用的标準模式.基本上都知道它.這種架構模式非常适合傳統的IT通信群組織結構,很自然地成為大部分應用的第一架構選擇。

軟體架構模式之分層模式

一、模式分析

分層架構模式裡的元件被分成幾個平行的層次,每一層都代表了應用的一個功能(展示邏輯或者業務邏輯)。盡管分層架構沒有規定自身要分成幾層幾種,大多數的結構都分成四個層次:表現層,業務層,持久層,和資料庫層。如圖一,有時候,業務層和持久層會合并成單獨的一個業務層,尤其是持久層的邏輯綁定在業務層的元件當中,形成。是以,有一些小的應用可能隻有3層,一些有着更複雜的業務的大應用可能有5層或者更多的分層。

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

架構裡的層次是具體工作的高度抽象,它們每一層都有特定的角色和職能,都是為了實作某種特定的業務請求。比如說展示層并不需要關心怎樣得到使用者資料,它隻需在螢幕上以特定的格式展示資訊。業務層并不關心要展示在螢幕上的使用者資料格式,也不關心這些使用者資料從哪裡來。它隻需要從持久層得到資料,執行與資料有關的相應業務邏輯,然後把這些資訊傳遞給展示層。各層實作的功能如下:

功能
表現層(presentation) 使用者界面,負責視覺和使用者互動
業務層(business) 實作業務邏輯
持久層(persistence) 提供資料,SQL 語句就放在這一層
資料庫(database) 持久化資料

二、關鍵概念——層隔離

上面圖一中,每一層都是封閉的。這是分層架構中非常重要的特點。這意味request必須一層一層的傳遞。舉個例子,從展示層傳遞來的請求首先會傳遞到業務層,然後傳遞到持久層,最後才傳遞到資料層。

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

如果隻是獲得以及讀取資料,展示層直接通路資料層,比穿過一層一層來得到資料來的快多了,那麼為什麼不允許展示層直接通路資料層?

這涉及到一個概念:層隔離。

層隔離是說架構中的某一層的改變不會影響到其他層:這些變化的影響範圍限于目前層次。如果展示層能夠直接通路持久層了,假如持久層中的SQL變化了,這對業務層和展示層都有一定的影響。這隻會讓應用變得緊耦合,元件之間互相依賴。這種架構會非常的難以維護。分層隔離使得層與層之間都是互相獨立的,架構中的每一層的互相了解都很少。

然而封閉的架構層次也有不便之處,有時候也應該開放某一層。如果想往包含了一些由業務層的元件調用的普通服務元件的架構中添加一個分享服務層。在這個例子裡,建立一個服務層通常是一個好主意,因為從架構上來說,它限制了分享服務通路業務層(也不允許通路展示層)。如果沒有隔離層,就沒有任何架構來限制展示層通路普通服務,難以進行權限管理。

例如下面的例子,新的服務層是處于業務層之下的,展示層不能直接通路這個服務層中的元件。但是現在業務層還要通過服務層才能通路到持久層,這一點也不合理。這是分層架構中的老問題了,解決的辦法是開放某些層。如圖三所示,服務層現在是開放的了。請求可以繞過這一層,直接通路這一層下面的層。既然服務層是開放的,業務層可以繞過服務層,直接通路資料持久層。這樣就非常合理。

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

開放和封閉層的概念确定了架構層和請求流之間的關系,并且給設計師和開發人員提供了必要的資訊了解架構裡各種層之間的通路限制。如果随意的開放或者封閉架構裡的層,整個項目可能都是緊耦合,一團糟的。以後也難以測試,維護和部署。

三、分層架構場景示例

為了示範分層架構是如何工作的,想象一個場景,如圖四,使用者發出了一個請求要獲得客戶的資訊。黑色的箭頭是從資料庫中獲得使用者資料的請求流,紅色箭頭顯示使用者資料的傳回流的方向。在這個例子中,使用者資訊由客戶資料和訂單數組組成(客戶下的訂單)。

使用者界面隻管接受請求以及顯示客戶資訊。它不管怎麼得到資料的,或者說得到這些資料要用到哪些資料表。如果使用者界面接到了一個查詢客戶資訊的請求,它就會轉發這個請求給使用者委托(Customer Delegate)子產品。這個子產品能找到業務層裡對應的子產品處理對應資料(限制關系)。業務層裡的customer object聚合了業務請求需要的所有資訊(在這個例子裡擷取客戶資訊)。這個子產品調用持久層中的 customer dao 來得到客戶資訊,調用order dao來得到訂單資訊。這些子產品會執行SQL語句,然後傳回相應的資料給業務層。當 customer object收到資料以後,它就會聚合這些資料然後傳遞給 customer delegate,然後傳遞這些資料到customer screen 展示在使用者面前。

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

四、分層架構的優缺點

優點

1、開發人員可以隻關注整個結構中的其中某一層;

2、可以很容易的用新的實作來替換原有層次的實作;

3、可以降低層與層之間的依賴;

4、有利于标準化;

5、利于各層邏輯的複用。

6、結構更加的明确

7、在後期維護的時候,極大地降低了維護成本和維護時間

缺點

1、降低了系統的性能。這是不言而喻的。如果不采用分層式結構,很多業務可以直接造訪資料庫,以此擷取相應的資料,如今卻必須通過中間層來完成。

2、有時會導緻級聯的修改。這種修改尤其展現在自上而下的方向。如果在表示層中需要增加一個功能,為保證其設計符合分層式結構,可能需要在相應的業務邏輯層和資料通路層中都增加相應的代碼。

3、增加了開發成本。

COLA 架構是什麼?

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

COLA作為架構,組要是制定了一套指導和限制,并将這套規範沉澱成Archetype。以便通過Archetype可以快速的生成符合COLA規範的應用。滿足COLA的應用是一個有清晰的依賴關系的分層架構,如下圖所示:

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

項目實戰

COLA 腳手架提供了兩個Archetype,分别是cola-archetype-service和cola-archetype-web

cola-archetype-service

用來生成純後端應用(沒有Controller),生成應用的指令為:

mvn archetype:generate  -DgroupId=com.alibaba.demo -DartifactId=demo -Dversion=1.0.0-SNAPSHOT -Dpackage=com.alibaba.demo -DarchetypeArtifactId=cola-framework-archetype-service -DarchetypeGroupId=com.alibaba.cola -DarchetypeVersion=2.0.0      

cola-archetype-web

用來生成Web後端應用(有Controller),生成應用的指令為:

mvn archetype:generate  -DgroupId=com.alibaba.demo -DartifactId=demo -Dversion=1.0.0-SNAPSHOT -Dpackage=com.alibaba.demo -DarchetypeArtifactId=cola-framework-archetype-web -DarchetypeGroupId=com.alibaba.cola -DarchetypeVersion=2.0.0
      

如何使用COLA

第一步:生成COLA應用

1、使用Archetype生成應用:

直接運作上面提供的Archetype指令就可以生成應用,如果你的Remote Maven Repository裡面沒有Archetype的Jar包,也可以自己下載下傳Archetype到本地,然後本地運作 mvn install安裝。

2、 檢查應用裡的子產品群組件:

如果指令執行成功的話,我們可以看到如下的代碼結構,它們就是COLA應用架構。

整潔面向對象分層架構 (Clean Object-Oriented and Layered Architecture)

第二步:運作Demo

1、進入在第一步中生成的應用目錄。

2、啟動SpringBoot:

首先在demo目錄下運作mvn install(如果不想運作測試,可以加上-DskipTests參數)。然後進入start目錄,執行mvn spring-boot:run。運作成功的話,可以看到SpringBoot啟動成功的界面。

3、 執行測試:

生成的應用中,已經實作了一個簡單的Rest請求,可以在浏覽器中輸入 http://localhost:8080/customer?name=World 進行測試。

4、檢視運作日志:

請求執行成功的話,可以在浏覽器中的傳回值中看到:"customerName":"Hello, World"。同時觀察啟動SpringBoot的控制台,可以看到LoggerInterceptor列印出來的日志。

Kotlin 開發者社群