天天看點

軟體架構的一緻性

在Brooks的最新力作《設計原本(The Design of Design)》一書中,提及“一緻性”對軟體的重要性。他認為:“一緻性應該是所有品質原則的根基。好的架構應該是直接的,人們掌握了部分系統後就可以推測出其他部分”。這種所謂“窺一斑而知全豹”的要求,實則是要求保持風格的一緻性。

  風格的一緻性

  許多軟體公司都會根據自身情況并結合業界規範制定符合本公司情況的編碼規範。例如對命名、格式等諸多風格的要求。這種編碼風格的一緻性是相對容易實作的。Brooks提到的一緻性,更多地是展現架構風格的一緻性。那麼,什麼是架構風格(Architecture Style)?在微軟撰寫的Application Architecture Guide 2.0一書中,将架構風格定義為一組原則的集合,是為系統家族提供抽象架構的粗粒度模式。架構風格可以改善設計,促進重用,為常見的問題提供可靠的解決方案。而Mary Shaw對架構風格的定義則顯得更加晦澀一些:“架構風格根據結構組織的模式定義系統種類。更具體地說,架構風格定義元件和連接配接器類型的詞彙及它們如何進行組合的一組限制。”顯然,Mary Shaw認為架構風格定義了架構組成元素的結構以及它們必須遵循的一些原則和限制。

  架構風格可能是對一些架構模式的運用,然而在運用模式之前,首先需要分辨系統的類别。例如系統如果是業務複雜的企業應用,那麼就領域層而言,就應該選擇領域模型(Domain Model),通過有效地利用對象、元件和服務保證系統的可重用性與可擴充性。而一旦選擇了領域模型,那麼在通常情況下,就不應該在同一個系統的其他子產品中采用事務腳本(Transaction Script)模式。否則,我們就違背了風格的一緻性。

  我們常常會将標明的架構風格作為整個系統架構的核心架構。了解了架構風格,就可以有助于了解整個軟體系統。例如,對于資料分析器系統而言,它的核心邏輯是輸入資料流、輸出資料流與分析算法之間的協作。由于分析算法是對資料流的一種篩選和過濾,我們標明的架構風格是采用管道-過濾器(Pipes and Filters)模式。那麼,在了解資料分析器的架構時,隻要掌握了管道-過濾器模式的核心思想,就能夠快速把握系統架構的核心。這有利于系統知識的延續,并保證整個系統的一緻性。

  當然,架構風格的選擇會因為關注點的不同,産生不同的解決方案。例如,從部署的角度來看,我們可能需要選擇分布式部署的實體架構;而對于同一個系統而言,由于需要考慮消息的傳遞,我們又可能選擇消息總線的方式。這與風格的一緻性并不沖突。我們隻需保證在同一個關注面上,保持一緻的風格即可。

  解決方案的一緻性

  風格的一緻性屬于軟體架構的層面,與之相似的是保證解決方案的一緻性。在整個系統架構中,解決方案必須是一緻的,否則就可能導緻混亂的架構與代碼。那麼,怎樣才能保證解決方案的一緻性呢?首要條件是在進行系統架構之前,我們必須根據系統與團隊的情況,制定被團隊成員廣泛接受的架構原則。例如,我們可以為系統制訂分層指導原則。對于領域層,我們遵循DDD的要求,為領域模型确定實體、值對象、聚合根、服務、工廠與資源庫之間的明确劃分,并明确地指出它們應該具備的特征。我們要求應用服務層不應包含任何業務邏輯,隻負責UI與領域層之間的消息傳遞,并可調用基礎設施中公共子產品的資料驗證、緩存和安全等功能。我們要求應用服務層不應保留業務對象的狀态,僅僅負責協調應用的活動,并要求所有公開在外的應用服務均定義為接口。

  在制訂了這樣的架構原則後,我們就可以統一系統的解決方案。例如遵循之前的分層指導原則,我們可以獲得如下的針對領域層的統一解決方案:

軟體架構的一緻性

  如果我們沒有保證解決方案的一緻性,并為此制訂統一的架構原則,就會使得團隊人員根據自己的意願來随意選擇解決方案。即使某個開發人員選擇的解決方案或許是最優的,但由于系統存在多種不同的解決方案,就可能使得整個系統陷入混亂之中。例如,在我曾經看到過的一個系統中,就存在不一緻的資料庫通路解決方案。在同一個系統中,子產品A使用了Spring的JDBC模闆通路資料庫,而子產品B則直接使用了JDBC。還是在這個系統,子產品C通過使用JDK的map來緩存頻繁讀取的值,而在子產品D中卻又使用了開源的EhCache作為緩存。

  為了保證解決方案的一緻性,除了需要事先制訂統一的架構原則之外,前面提到的風格一緻性也能夠給予統一的指導和限制。事實上,我們可以将解決方案的一緻性了解為對風格一緻性的一種實作。除此之外,團隊成員之間的協作與溝通,以及必要的架構評審與代碼走查,都能夠在一定程度上避免解決方案的不一緻。

  形式的一緻性

  保持系統架構在形式上的一緻性,常常是架構師的有意為之,其目的是希望保持架構的簡單性。最能展現形式一緻性的一個原則是“慣例優于配置”。這裡所謂的“慣例”,可以了解為架構對實作的一些限制。我們可以根據事先制訂的預設規則,通過反射技術完成對象的建立,對象的協作,甚至是應用程式的組裝。“慣例優于配置”的關鍵,就在于它規定了形式上的一緻性。以Ruby on Rails為例,通過事先确立Model、View和Controller的目錄結構與命名規範,強迫開發人員對系統進行MVC的劃分,并嚴格遵守架構制訂的規範。在程式運作時,Rails會将分離的部分組裝在一起。組裝的過程預設按照命名約定與慣例進行,在一般情況下就不需要任何外部的中繼資料配置資訊。下圖是Rails的MVC架構: 

軟體架構的一緻性

  當用戶端向服務端送出請求後,Dispatcher會對請求的url進行解析,并判斷應該将請求發送到應用程式的哪個部分,以及如何解析這一請求。在尋找到正确的controller與action之後,就可以通過該action來處理請求。action可以查閱請求中攜帶的資料,可以與模型互動,也可以調用别的action。最後,action會為視圖準備充分的資訊,視圖則将所需的資訊展現給使用者。因為在形式上能夠保持一緻性,架構就變得簡單,參與的各個元件能夠做到各司其職,職責清晰,意圖明确。

  這種形式的一緻性基于一種樸素的思想,就是有限的限制比完全的開放更容易實施和遵循。正如社會總要有一套被人廣泛認同的規則,來限制每位公民的行為,否則整個世界就會亂了套。形式一緻性的本質在于概念的完整性,而它的基礎則在于約定。架構的複雜性在于我們無法為混沌的系統做出正确的決策,如果能夠為我們所要解決的場景抽象出整體的概念,就能夠最大程度地對模型進行簡化,進而給出一緻性的約定。Rails利用現有的MVC模式,通過約定與慣例在形式上的一緻性,實作了Web架構的簡化。如果我們觀察Maven的目錄結構,就會發現Maven在針對依賴管理這樣一個場景,同樣提出了自己的概念模型,并在形式上規定了架構的一緻性:

軟體架構的一緻性

  簡潔的架構常常能展現一種獨到的美,而具有一緻性的架構則會給軟體系統帶來和諧與平衡。架構風格的一緻可以保證系統架構的統一,設計人員隻要抓住了架構的風格特征,就能夠把握這個系統的“神”,進而促進對系統架構的了解。對架構風格的重視,還有利于架構級别的資源重用,通過對問題域的分析,判斷它應該屬于哪一種架構風格的分類,就能夠找到适合架構的原則、模式或現有的平台和架構。解決方案的一緻性可以避免混亂的軟體架構,促進團隊成員之間的交流與協作,規避因為解決方案不一緻而導緻的資源浪費。保持一緻的解決方案還可以保障軟體品質,因為很多潛在的隐患與缺陷,恰恰都是因為不同的解決方案帶來的沖突導緻的。形式的一緻是簡化的前提,并能夠保證系統概念的統一,通過抽象簡化概念模型,并制訂一緻的架構約定,就能夠簡化整個架構體系,降低實作的難度。

轉載于:https://www.cnblogs.com/SophiaTang/archive/2011/12/21/2296308.html