1. 程式人生 > >架構就是關注點分離

架構就是關注點分離

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

文 / 王海鵬

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

例如:“註冊使用者可以向自己的相簿上傳圖片,並與好友分享”。這是一項功能性需求。它告訴了我們在系統的業務架構中,會出現“註冊使用者”“相簿”、“圖片”、“好友”等組成部件,它們之間存在著相互關係。而“系統可以支援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年畢業於華東師範大學物理系。擁有理學士和文學士學位。獨立的軟體開發者、培訓師和諮詢師,也是十餘本軟體開發書籍的譯者。從事軟體開發十餘年,目前主要的研究領域是軟體架構和方法學,致力於提高軟體開發的品質和效率。

原文連結: http://history.programmer.com.cn/675/