架構就是關注點分離

要設計良好的架構,必須做到關注點分離,這樣可以產生高內聚、低耦合的系統,這是美麗架構的終極原則。

文 / 王海鵬

 什麼是架構? 每個人可能都有自己對架構的定義。我比較喜歡的定義是:“架構是系統的組成部件及其之間的相互關係。”根據觀察者的視角不同,架構又可以分爲業務架構和技術架構。一般來說, 功能性需求會對業務架構產生影響, 而非功能性需求會對技術架構產生影響。

例如:“註冊用戶可以向自己的相冊上傳圖片,並與好友分享”。這是一項功能性需求。它告訴了我們在系統的業務架構中,會出現“註冊用戶”“相冊”、“圖片”、“好友”等組成部件,它們之間存在着相互關係。而“系統可以支持10萬併發用戶,並在需要時可以方便地伸縮,擴展到支持100萬到1000萬的併發用戶”,則是一項非功能性需求。它告訴了我們系統在性能、負載、吞吐量、可伸縮性方面的特性,目標系統的架構必須對這些特性提供支持。

架構體現的是對複雜系統的分解設計。而如何進行分解,則是軟件設計領域永恆的話題。實際上,架構體現的是關注點分離的原則和方法。經典的三層架構,由展現層、業務邏輯層和持久層構成;其中體現了我們對用戶界面、業務邏輯和數據持久的關注點分離。這種架構從命令行時代的軟件就開始有了,直到最新的AJAX 加RESTful的Web 應用架構中仍然可以看到它,因爲這種關注點的分離在這些應用中是必要的。

我們可以在Web 應用中不採用三層架構,也就是不進行這種分離。我們可以在JSP/ASP/PHP中混合用戶界面、業務邏輯和數據持久層。但是這樣的代碼是難以維護的,難以適應大規模項目開發,難以適應將來的變化。關注點不分離的代碼爲閱讀和理解制造了更多的障礙。用戶界面、業務邏輯和數據持久三者的分離,讓它們能夠相對獨立地進行變化,比如實現新的用戶界面方式、改變業務邏輯和採用新的數據持久機制。

依賴注入的架構方式因Spring、Guice 等框架而被廣大Java 程序員所熟悉,進而擴展到.NET等其他語言和平臺,它也體現了關注點的分離。

首先,依賴注入體現了“做什麼”和“怎麼做”的關注點分離。學過C語言的程序員都知道,這種關注點的分離有着悠久的歷史,它表現爲.h文件和.c文件,一個規定函數原型,一個規定函數實現。這種關注點分離後來還在面向對象的設計中表現爲“針對接口設計”,於是我們在依賴注入的架構方式中,看到了許多的接口,以及接口的不同實現。組件的使用者關注組件做什麼,組件的實現者關注組件怎麼做。其次,依賴注入體現了對實例生命週期(特別是實例創建)和組件裝配的關注點分離。我們可以集中指定對象創建的方式,方便靈活地改變系統的裝配方式。通過這樣的關注點分離,依賴注入的架構讓系統變得更靈活,讓組件的實例化和組裝方式集中在系統的一個局部來確定,而不是分散在系統各處。

《彩色UML建模》一書中提出了4種領域無關的架構型,體現了業務流程、業務事件、參與者角色、具體參與者、分類分組的關注點分離。它研究的是業務架構,告訴我們如何設計一些組件來體現業務邏輯。

以ATM機取款爲例,它包含一個業務流程,由身份認證、取款、打印憑據等事件組成。單獨來看取款這個事件,彩色UML方法會在模型中體現出“取款(時刻/ 時段)”、“賬戶(物品)”、“信用卡(物品)”、“ATM機/ 取款櫃檯(地點)”等組件。這樣的關注點分離,使得這一組取款組件可以從業務流程中獨立出來,所以它也可以參與其他業務流程,如櫃檯取款。

REST是一種Web應用架構風格,它的主要特點包括:

  • 資源是由URI來指定。
  • 對資源的操作包括獲取、創建、修改和刪除資源,這些操作正好對應HTTP協議提供的GET、POST、PUT和DELETE方法。
  • 通過操作資源的表形來操作資源。
  • 可以通過內容協商機制來取得同一資源的不同物理表現形式,可以是XML、HTML、JSON或其他格式,這取決於請求者是機器還是人,是消費Web服務的客戶軟件還是Web瀏覽器。

在REST架構風格中,體現了對資源命名、請求處理和資源物理表現形式的關注點分離。

由於實現了這些關注點分離,REST有下面這些好處:

  • 可以利用緩存Cache來提高響應速度。
  • 通訊本身的無狀態性可以讓不同服務器處理一系列請求中的不同請求,提高服務器的擴展性。
  • 瀏覽器即可作爲客戶端,簡化軟件需求。
  • 相對與其他疊加在HTTP協議之上的機制,REST的軟件依賴性更小。
  • 不需要額外的資源發現機制。
  • 在軟件技術演進中的長期的兼容性更好。

AOP(面向方面編程)也是關注點分離思想的一種體現。記日誌是說明AOP 思想的一個常用例子。當我們在業務代碼中嵌入很多日誌代碼時,業務代碼的可讀性就下降了,因爲業務邏輯和日誌是兩個不同的關注點。通過AOP技術來分離這兩個關注點,就提高了代碼的可讀性和可維護性。

Ivar Jacobson在他的《Aspect-Oriented Software Developmentwith Use Case》一書中, 提出了AOP思想與用例技術結合的方法。例如,在“用戶利用電話系統通話”和“對用戶的通話計費”這兩個用例中,我們的關注點是不同的。但是如果不採用AOP的方法,實現代碼中必然將這兩個關注點的代碼編織在一起。如果對一個業務過程有許多不同的關注點,代碼就變得複雜而難讀了。於是Ivar提出,分離兩個關注點, 再利用AOP的技術將它們最終編織在一起。這樣,我們就能單獨面對一個方面的關注點。

AOP技術用一種特別的方式實現了關注點分離,它的好處是明顯的,但也有一些不足。比如對於編織後的系統除錯,會因爲執行流的跳轉而變得比較複雜。這時候,我們需要通過一些其他技術來彌補,例如迴歸測試。我們在實現了“用戶利用電話系統通話”後,寫一個迴歸測試將工作成果確定下來。在我們實現之後的業務關注點時,經常跑這個迴歸測試,確保不會因爲新的編織而在系統中引入缺陷。

EJB技術雖然在早期受到了一些詬病,但是它的架構設計總體上仍然是非常漂亮的。EJB體現了分佈式計算、持久、實例化、緩衝、事務、安全性等關注點的分離。

Google提出的MapReduce技術是一種新的集羣計算思想, 它體現了分佈式並行計算的關注點分離。Apache 的Hadoop項目就是這種技術的一個實現。通過這種技術,實現了對大規模分佈式系統的性能、可伸縮性、可靠性的關注點分離。程序員可以在不瞭解太多分佈式計算細節的情況下,開發出大規模分佈計算程序。

關注點分離帶來的是高內聚、低耦合的系統,這是美麗架構的終極原則。在實踐中,這種關注點分離可以是一開始就設計好的,也可以是逐漸形成的。如果是逐漸形成的,那就是所謂的演進式架構。例如,我們可以先不實現持久機制,在項目進行到一定階段再來實現。或者在以後方便地更換持久機制。

我們在系統分析時確定系統都有哪些關注點,然後設計一個架構來支持這些關注點的分離,最終將得到在相同的關注點上高內聚,在不同的關注點上低耦合的設計。

 作者簡介:

王海鵬,1994年畢業於華東師範大學物理系。擁有理學士和文學士學位。獨立的軟件開發者、培訓師和諮詢師,也是十餘本軟件開發書籍的譯者。從事軟件開發十餘年,目前主要的研究領域是軟件架構和方法學,致力於提高軟件開發的品質和效率。

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