應用程序架構本質,第 2 部分: 設計模式入門

對於應用程序架構師而言,標識、應用和記錄模式就像每日三餐一樣普遍。模式涵蓋很多複雜的方面,從應用程序體系結構的大型結構到特定的設計問題解決方案均包含在其中。爲了保證設計的成功,必須考慮並能夠應用現有模式。在本文中,您將瞭解如何標識在設計中重複出現的模式,以及如何記錄其特徵、優勢和缺點。

從需求到形成有效的應用程序體系結構需要使用模型。建模 是記錄模型在應用程序域內的狀態和行爲的過程。需要考慮這些模式才能幫助解決設計問題。隨着時間的增長,域內的模式會變成交流設計優缺點的一種語言。

在關於應用程序體系結構的本系列的第二部分(即本文)中,我們將瞭解與設計模式相關的技能、工具和里程碑,從而幫助您解決常見問題。設計工作至少有一部分需要考慮如何解決存在衝突的各個需求,這些需求通常表述爲影響因素 (force)。模式標識適用的影響因素,並提供對這些影響因素進行調和的解決方案。

技能和能力

作爲應用程序架構師,您應該能夠辨認需求和系統設計中涉及的影響因素。您應該熟悉現有模式,並能夠標識和記錄新的域特定模式。最後,您應該能夠應用(或創建機制來便於其他人應用)域或系統設計內有用的各種模式。

熟悉現有模式

儘可能熟悉現有模式。(請參見參考資料部分提供的指向模式語言和存儲庫的鏈接。)通過全面認識和了解現有模式,可快速地標識和創建模式。不過請注意,不要對所有設計問題都勉強套用現有模式。

標識模式

能夠確定在需求集或系統設計中適用的模式,這是應用程序架構師的一項主要技能。雖然這樣說,但我認爲開發生命週期中不應該存在模式相關的階段或活動。由於模式出現在各個抽象級別,且涉及多個開發活動,甚至可以應用於開發模型本身,這就使得在需要時以及針對危險執行應急措施時都自然而然地想到進行模式標識和應用,但您並不需要過於糾纏這方面的工作。

記錄模式

我此處非常想討論兩個領域:模式內容的記錄和模式用法的記錄。您不僅應該能夠創建易於理解的模式的影響因素、上下文和解決方案方面的描述,而且還應該記錄模式在設計和實現中標識、應用或適用的位置。隨着時間的增長,通過簡單的收集和重構,就應該能夠構建適用於應用程序域的涵蓋範圍更爲廣泛的模式語言。我並不是建議在工作中每次使用模式時都進行記錄。我們習慣於遵循模式行事,這種自然的驅使力量無法抗拒。請僅記錄有助於提高系統整體質量的重要設計方法。

當然,您應該熟悉一個或多個有關模式記錄的行業方法和格式,而且需要熟悉特定於您的環境的任何標準。有關現有模式存儲庫和書籍的信息,請參見參考資料中提供的鏈接。

抽象

我在本系列的 第 1 部分曾提到,抽象是需求分析的一項關鍵技能。勿庸置疑,這至少在有效使用設計模式方面也非常適用。當更改設計,以適應新需求時,請稍稍後退一步,抽象出細節,直到得到軸心點,在不影響現有元素的情況下可以在此軸心點處理特定類型的更改。這將很可能涉及到將現有模式作爲候選解決方案來提供恰當的分離。

大部分模式都基於可插入性 (plugability),也稱爲模板與掛鉤 (template-and-hook)。 將定義通用行爲(模板),並提供域特定的行爲和域類提供的狀態(提供掛鉤)。這是作爲大部分模式基礎的元模式,務必在開發自己的模式過程中記住這一點。

體系結構風格

體系結構風格 處理應用程序的全部或部分總體結構。特定的風格提供對應用程序的一個或多個質量屬性的改進——通常以犧牲其他屬性爲代價。例如,管道和篩選風格允許在鏈的組件間實現方便的可組合性和鬆散偶合。不過,在此風格中的可分佈性和可預測性會受到負面影響。您應該對其中的大部分結構設計原則加以熟悉——特別是您的應用程序域中應用的結構設計原則。另外,還要注意每個風格所具有的優缺點。

建模

正如我在本系列的 第一篇文章中提到的,建模是應用程序架構師的一項關鍵技能。大部分與設計模式相關的操作都在建模領域中進行。甚至底層編碼模式也可應用於此領域,因爲可以將代碼視爲解決方案的另一個模型。您應該能夠使用建模語言實現模式,以在其他項目中使用,而且應該能夠將現有模式應用到模型。

爲了將模式作爲模型實現,需要使用建模語言創建屬於模式的模板內容。對於統一建模語言(Unified Modeling Language,UML),這可以爲單個包,其中包括相應的子包、類、關係和接口;或者可以爲完整的建模項目,其中包含針對模式解決方案各個方面的多個模型。無論使用哪個工具進行建模,我都找到了創建這些模板的方法,以便重用整個體系結構模型或單個分析模式。

目前有多種將模式作爲首要概念處理的多種建模工具可用。在這些環境中,可以爲模型創建和應用模式,並能利用各個級別的自動化功能來支持將模式角色映射到模型對象。(有關更多信息,請參見 工具和技術部分。)

要將模式應用到模型,涉及到將模式解決方案中的通用規則映射到模型中特定的域類。爲此,您必須將模式需要的所有狀態和關係添加到域類中。您還可能會希望更改模式的通用方面的名稱,以與域的相應語言對應。例如,會計分析模式可能會包括 Account 和 Customer 之類的角色,而兩個角色分別又涉及 getCustomergetAccount 之類的操作。如果您的域包括希望對其應用模式角色的 CreditCardMember,則可能會希望更改操作,以與之對應(即 getMembergetCreditCard)。您當然應該能夠進行此映射工作。如果您的工具未實現此流程的自動化,請開發自己的腳本或宏。

 




回頁首


工具和技術:分解應用程序

現代企業應用程序已變得相當複雜。應用程序體系結構中涉及的相互依賴組件的數量正在不斷地增加。不過,我們仍然很少充分利用這種體系結構類型所帶來的靈活性。讓我們瞭解一下應用程序的實際情況以及企業應用程序的結構正如何發展爲“分解”應用程序。

我將首先給出自己關於應用程序構成部分的簡單定義。應用程序 是提供對計算資源的訪問以支持特定用途的構造體。因此,大部分應用程序都包含以下組件:

  • 規則——應用程序實現指定適用輸入、輸出可見性等的規則。
  • 工作流——應用程序通過受支持的活動定義步驟序列。請注意,有些應用程序相對而言是“沒有模式”,幾乎不涉及工作流。另外,還可以利用上面提到的規則定義工作流。
  • 子系統集成——應用程序可以與一個或多個子系統交互,在這些子系統之間提供受控集成。
  • 事件——應用程序管理與外部及子系統間的事件流。此過程可以非常複雜(如異步事件隊列),也可以非常簡單(如重複調用子系統功能來調用行爲、讀取狀態或傳播狀態的主循環)。
  • 信息模型——應用程序在子系統的基礎上定義其信息模型。信息模型是子系統狀態和應用程序特定狀態的組合視圖。應用程序通常必須提供子系統間的一些信息映射。
  • 綁定與傳播——應用程序提供包括外部和動態配置、子系統狀態視圖和應用程序特定狀態視圖的信息模型。應用程序代碼的大部分都涉及到在子系統間保持這些信息同步、響應更改以及將更改傳播到相關組件。

所有這些導致了模式的出現:隨着包括越來越多的支持應用程序功能的通用組件(例如,規則引擎、工作流引擎、企業服務總線),應用程序會變得越來越含混和分散,所包含的各個應用程序支持組件的聲明規範和配置集合也變得越來越大。如果您是規模相當大的企業的架構師,請務必記住這一點。如果您所屬的企業較小,也不要認爲自己可以不受分解趨勢的影響。您遲早(如果尚未開始的話)都會採用這種方式構建應用程序。

 




回頁首


工具和技術:層次

到目前爲止,我已經討論瞭如何在多個抽象級別、應用程序整個週期甚至開發生命週期本身中標識、記錄和應用模式。有了所有這些潛在的模式後,您需要採用某種方式對其進行組織。限制適用模式的一個方法是,根據其應用到的體系結構層次對模式進行分類。

圖 1 中的關係圖顯示了不同類型的層次一種可能的安排方式。概念層次(業務、應用程序、信息和技術體系結構)顯示在右側。垂直部分是與應用程序及信息體系結構相關的邏輯層次。底部是技術層次,顯示邏輯層次映射到物理基礎設施的方式。這個安排顯示了一個瘦客戶機部署,其中的全部表示和一些應用程序邏輯都映射到了客戶機物理層。


圖 1. 層次映射
層次映射

概念層次

概念層次 將非常抽象的模式空間劃分爲業務域模式、解決方案設計模式和基礎設施模式。

邏輯層次

邏輯層次 根據層次的體系結構功能劃分模式空間。可以採用多種方式定義邏輯層次,但通常分爲三個或四個級別:

  • 表示——支持信息顯示和捕獲外部事件及請求的組件。
  • 應用程序——實現應用程序流、聚合信息和調用業務事務的組件。
  • 業務——實現業務實體、規則、流程和事務的組件。
  • 數據——提供對持久性數據和其他外部數據的訪問的組件。

邏輯層作爲應用程序部署體系結構的一部分射到物理層。這些映射也包含一些公用模式。例如,瘦客戶機 或獨立體系結構會將全部或大部分邏輯層映射到客戶機物理層。分佈式企業 Web 應用程序很可能會將邏輯層分佈到一系列物理層。最後,富客戶機 體系結構將表示層(還可以包括應用程序層)映射到客戶機。

應用程序體系結構模式或原型 涵蓋所有邏輯層,定義完整應用程序的總體結構。其他模式將位於較低的粒度級別,作用於單個層次中的組件或組件交互設計。另一類模式涵蓋兩個層次間的交互。這種劃分模式空間的方式至少能讓您在尋找現有模式或對新模式進行分類時找到着手點。

物理層次

物理層次 根據模式應用的物理部署平臺對模式空間進行劃分。這個類別中的模式與解決特定平臺上的問題相關。例如,您可以有一個通用會話狀態管理模式以及多個平臺特定的模式,用於在 Microsoft® ASP.NET 和 JavaServer Pages (JSP) 站點中實現通用模式。

J2EE

Java™ 2 Platform Enterprise Edition (J2EE) 標準將應用程序的邏輯層作爲容器堆棧定義。所定義的容器有:

  • 客戶機容器——支持對應用程序資源的客戶端訪問。
  • Web 容器——處理客戶機請求和用於進行顯示的格式數據。
  • EJB 容器——爲業務邏輯的高可用性、高性能實現提供環境。
  • 連接器——提供對數據庫和大型機等外部資源的訪問。

 




回頁首


工具和技術:組件設計模式

基於組件的軟件工程(Component-based Software Engineering,CBSE)通過接口連接組件來構造系統的方式。重要模式包括契約式設計、定義良好的接口、可組合性、可預測的行爲和組件測試。目前已經有很多關於組件的分佈、交互和構造的模式和模式語言。我下面將給出一些例子:

  • 交互模式——組件交互模式可幫助解決與體系結構的組件的協作、通信及協調相關的設計問題。與體系結構風格類似,這些模式處理應用程序體系結構的大型結構。例如,“抽象交互”(Abstract Interactions) 模式建議將組件交互作爲抽象接口進行定義。通過與“組件總線” (Component Bus) 模式結合(以及精心的設計),可以創建沒有耦合的靈活組件體系結構。
  • 分佈模式——組件分佈模式處理與異類平臺和環境中分佈組件相關的問題和影響因素。
  • 連接模式——組件連接模式處理組件如何“連接”到一起(動態或靜態)。
  • 行爲模式——組件行爲模式處理組件及其環境間的交互。
  • 部署模式——部署模式幫助處理組件部署相關的影響因素。例如,在分佈式組件體系結構中,組件間的延遲有時候會由於分佈開銷而不能接受。組件打包模式允許在靈活性和分佈式環境的其他屬性以及“本地”組件交互的可預測性能之間求得平衡。
  • 業務組件工廠——業務組件工廠方法在 Peter Herzum 和 Oliver Sims 撰寫的書中進行了詳細說明(請參見 參考資料)。此書給出了完整的模式框架,爲企業的業務組件的規範、構造和部署工作提供支持。
  • 依賴項注入—— 依賴項注入 是用於將對象或組件連接在一起的一項技術。依賴項注入不會構建對自身進行初始化的組件(包括創建依賴對象),而是將提供一個容器(或工廠),以查找或創建依賴對象和對所請求的對象調用 setter 掛鉤來初始化其引用。通過此功能,可方便地重新配置組件,並能夠方便地支持可插入設計,從而避免組件之間的硬編碼依賴關係。這種類型的容器的一個很好的示例就是 Spring(請參見 參考資料)——支持爲傳統 Java 對象(Plain Old Java Object,POJO)進行依賴項注入的開源容器。組件使用可擴展標記語言(Extensible Markup Language,XML)配置文件連接在一起。

 




回頁首


工具和技術:企業集成模式

企業集成模式討論企業內應用程序和系統的大規模集成。這些模式側重於應用程序及其他信息系統組件間的通信。消息(以及消息的創建、路由、響應和轉換)是這些模式中的主要概念。

 




回頁首


工具和技術:企業應用程序模式

企業應用程序模式處理應用程序及其子系統的體系結構內的設計問題。這些模式討論表示、到關係數據存儲的映射、域邏輯、應用程序狀態管理和創建的應用程序功能。

 




回頁首


工具和技術:分析模式

分析模式處理業務域或解決方案域。這些模式解決在建模業務流程和實體過程中及業務事務的實現方法中的設計問題。

 




回頁首


工具和技術:原型 (Archetype)

原型 是在某個域或多個域中重複出現的通用概念和模式。可以將其映射到特定的域,並能用於進行模型轉換、代碼生成等工作。PartyInventoryPurchase OrderMoney 就是這方面的例子。雖然和分析模式類似,但原型的抽象級別更高。原型可以包括可選功能、選擇功能或基於業務上下文的完整結構變體(異形結構)。

 




回頁首


工具和技術:表示模式

表示模式處理信息的顯示及處理操作信息或調用應用程序流的事件。此領域的模式的主要目標是將表示特定的方面從應用程序及業務邏輯分離出來。其中的一些例子包括:

  • 模型-視圖-控制器(Model-View-Controller,MVC)——此模式將應用程序模型的可視表示形式(視圖)從模型本身分離。控制器負責更新視圖和調度視圖級別的事件。
  • 表示-抽象-控制(Presentation-Abstraction-Control,PAC)——此模式在很多方面與 MVC 相似,也將功能分離爲類似的角色。PAC 比 MVC 更爲抽象和通用,可能更適合在用戶界面(User Interface,UI)之外的領域使用。從某些方面而言,此模式與層次相關,因爲可以使用類似的模式來設計每個層次邊界的交互。一個層次的模型就是另一個層次的視圖。通過將此模式作爲組織體系結構原則使用,可爲“可插入”體系結構提供極大的支持。
  • 前端控制器 (Front controller)——前端控制器適用於請求/響應類型的交互,將使用單個對象來接收請求、進行調度、路由並收集響應。
  • 顯示服務器——此模式將表示實現定義爲顯示信息和訂閱事件的抽象服務。此模式最成功的用法是 X Windows 系統。

 




回頁首


工具和技術:面向服務的體系結構

從很多角度而言,面向服務的體系結構(Service-Oriented Architecture,SOA)是對基於一組常見影響因素(與以組件爲基礎的應用程序相關)的模式集的標準化。組件充當服務實現,而服務相關的基礎設施處理關於連接、交互等等的決策,如上面的 工具和技術:組件設計模式中所述。

服務組件體系結構

服務組件體系結構(Service Component Architecture,SCA)是定義了一種聲明語言(基於 XML)的 IBM 項目,可將此語言用於指定組件的組裝以及其內部和外部服務接口依賴關係。可以採用 Spring 的方式將組件連接到一起,但 SCA 將組件連接功能安排到了實現模塊的分佈邊界之外。此標準現在由 Open Service-Oriented Architecture Collaboration 進行管理。

模型驅動的體系結構

模型驅動的體系結構(Model-Driven Architecture,MDA)中支持模型轉換和充實的功能也可以支持基於模式的就地模型轉換。IBM® Rational® Software Modeler 和 Rational Software Architect 提供了定義模式並將其直接應用於模型的支持。ArcStyler(iO Software 的產品)爲 MDA 提供了成熟而廣泛的支持,可以用於應用模式轉換。

 




回頁首


里程碑

架構師的工作中總會涉及到模式的標識和應用。由於這個原因,很難在項目週期中確定特定的點來說明模式工作的進展。不過,我希望在此討論應用程序生命週期中一些重要的部分,應該在這些方面尋找和確定應用程序中的模式。

體系結構

應用程序體系結構是主要的交付內容,而在大多數情況下,模式在其開發中扮演着極爲重要的角色。標識體系結構風格及在體系結構中使用的其他大型模式具有多方面的作用。模式可以帶來以下好處:

  • 使體系結構更易於理解和說明。
  • 通過所使用的模式的已知特徵重點突出主要體系結構決策和優缺點。
  • 允許重用模型和事項的較大組成部分,特別組織依賴於最佳實踐模式作爲框架和工具時更是如此。

域模型

域建模並非真的很新,但關於如何進行相關工作的信息卻比較少。Eric Evans 撰寫的書 Domain-Driven Design(請參見 參考資料)提供了一組用於建模域的模式,其中包括用於標識及確定域邊界和細化域設計的技術。

通過使用這些技術來記錄域,將極大地提高應用程序體系結構的有效性和持久適用性。

分析模型

大部分域通常都得到了大家的認可和實現了自動化。因此,域模型能夠充分地利用設計良好模式語言。請尋找爲您的域提供全部或部分支持的可用模式。如果沒有此類模式,請考慮自行創建一個。這些模式應該爲在域或標準模式中經常重複出現的模式(如 money 和 currency 模式)。

設計和實現

同樣,在應用程序生命週期的設計和實現階段有很多方法和時機使用模式,很難指定與模式相關的特定交付內容。不過,基於模式和抽象的恰當使用的體系結構將更易於理解和維護。您應該能夠演示在何種情況下使用模式(在特定區域內使用或作爲體系結構指導原則使用)處理了某個需求或提高了體系結構的總體質量。

方法

在我看來,建議的開發方法屬於應用程序體系結構的一部分。在網絡和一些文獻資料中提供了很多開發模式。其中一些重要的例子有:

  • 統一流程 (Unified process)——一種迭代式的分階段開發方法,在 IBM Rational 和 IBM Rational Unified Process® (RUP®) 的推動下得到了廣泛的應用。RUP 包括可以用於配置基本統一流程框架的工作流和模版。
  • RM-ODP——開放式分佈處理的參考模型(Reference Model for Open Distributed Processing,RM-ODP)是系統體系結構規範的建模方法。RM-ODP 將系統的規範和建模拆分爲視角,其中每個視角處理一組特定的考慮事項。
  • 極限編程(Extreme Programming,XP)——XP 是輕量級方法,避免了與“測試第一”方法相關的正式建模和分析。系統需求作爲用戶案例捕獲。用戶案例轉換爲相應功能的測試,然後編寫代碼實現測試用例。此模式最適合用於小型的技能嫺熟的團隊,難以擴展爲大型項目。
  • Scrum:另一個輕量級方法,側重於短期的成就(團隊針對其提交特定的交付內容)。會頻繁評估進度並根據風險和需求優先級的要求調整工作投入。

 




回頁首


總結

處理模式是架構師日常工作中所必須涉及的內容。正如我在 第 1 部分提到的,抽象和建模是兩項關鍵技能。二者都與模式有關係。您必須能夠將相關抽象從具體需求中提取出來,從而不僅形成體系結構的總體概貌及其指導原則,還能處理關鍵設計問題,或在設計和實現的較低級別對風險帶來的更改做好準備。

另外,並非所有內容都是模式,也不是每個模式都值得記錄和發佈。應用不恰當或不必要的模式可能會莫明其妙地讓您的設計變得複雜。請始終記住每個模式的優缺點,並對影響其使用的實際影響因素進行評估。

 

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