架構愿景是一個很簡單的模式,在軟件開發中所占的時間也很短。但是這并不意味著架構愿景不重要。相反,它會是設計過程不可或缺的一環。
Context
在單次的迭代開始階段,我們已經收集好了單次迭代的需求。
Problem
架構和分析設計是密不可分的,有時候很難說得清楚架構的定義,但架構應該能夠描述軟件的整體。架構包括了軟件的各個方面,但是每一個設計細節總是需要單獨考慮,這時候就會出現設計細節之間、以及設計細節和架構之間的不一致。
架構設計的各個部分之間的設計沖突是很容易發生的。發生的概率及頻率和團隊的規模成正比、和溝通的頻度及效果成反比。在很多次的項目開發過程中,我們發現了多處的相同功能的代碼,原因是代碼的作者并不知道別人已經實現了這個功能了。這可能只是浪費了一點精力,可如果不同模塊間的設計沖突導致了軟件無法正常運行的時候,我們就需要坐下來好好的審視,究竟發生了什么。
Solution
我們需要建立一個架構愿景。架構愿景應該能夠提供軟件全局視圖,包括所有的重要部分,定義了各個部分的責任和之間的關系,而且還定義了軟件設計需要滿足的原則。而這個架構愿景的設計,應該是滿足源自需求模式的,也就是說,部分的劃分和部分的設計,都是根據需求而進行的。同時,架構愿景應該要能夠滿足架構的其它各種特點,例如簡單、可擴展性、抽象性。簡單來說,我們把架構愿景當作是一個mini的架構設計。
由于我們是在單次的迭代中討論架構愿景,因此從整體上考慮,架構愿景是也是在不斷的變化的。這是很自然的,因為架構愿景代表了架構的設計,架構愿景的演進代表了架構設計的演進。
架構的愿景是相對于一個范圍來說的,在一個特定的軟件功能范圍之內,談架構愿景才有實際的意義,例如針對軟件的全局或某個子模塊。在這個特定的范圍中,訂立了架構愿景之后,這個范圍內的所有設計原則將不能違背架構愿景。這是非常重要的,是架構愿景的最大的用處。有了這樣的保證,我們就可以保證設計的一致性和有效性。任何一項設計的加入,都能夠融入到原先的架構中,使得軟件更加的完善,而不是更加的危險。
當然,要做到這一點并不是一件容易的事情。特別需要指出的是,架構愿景模式僅僅是實現該目的的一條道路,并不是一個充分條件。如果在設計中愿景不能夠貫徹其意志,或是愿景制定本身就存在問題,那么要想達到上述的效果,幾乎是不可能的事情。此外,該模式僅僅只是達到該目的的第一步,我們在接下去的模式中會發現還需要很多方面的配合。
架構愿景的層次
我們根據架構適用范圍的不同,把架構愿景分為幾個類別討論:
軟件全局
軟件全局的架構是我們所最關心的,因此也會花費最多的筆墨。
軟件全局中的架構愿景一般很難具體化到代碼級別,其實你會發現,就算是具體化到了代碼級別,也會因為實際中存在的問題,導致代碼沒有太多的價值。因此,為軟件全局設置的架構愿景可以以原則、或是模式名的方式體現,并用自然語言或偽代碼描述。例如,可以為一個系統規定三層架構作為其愿景,并指出三層的分類原則。注意,我們需要指出分類原則,否則規定三層架構并沒有太大的意義,因為三層架構隨著實現平臺的不同、開發人員的不同而有很大的差異,如果不能夠規定一個可操作的規范,那么愿景是沒有意義的。在Java環境下,我們可以這樣說:
"客戶端采用前端瀏覽器界面,業務邏輯采用servlet,配合JSP編寫,瀏覽器到服務器的數據采用集中處理,具體的方法是在業務邏輯和前端瀏覽器之間采用Front Control模式,接受前端瀏覽器傳送過來的數據,并指派給相應的業務邏輯處理。數據的合法性檢驗分為兩個部分:和業務邏輯無關的基本合法性驗證在前端使用Java Script處理,和業務邏輯相關的合法性驗證在業務邏輯層處理,可以使用一個集中的servlet專門處理錯誤情況。"
而在Windows環境下,我們知道三層結構的分界和Java中的并不相同(關于這一點,下一篇的文章中將會有詳細的描述),我們可以在業務邏輯層或顯示層直接操縱數據,非常的方便,因此,在Windows中的架構愿景的描述又不一樣。另外,在非面向對象的環境中,在分布式的環境中,在Lotus Notes的環境中,其架構的描述都不一樣。
注意到,架構愿景的制定是根據不同的應用環境而變化的,這一點我們在文章的一開始就強調過,這里又出現了相同的問題。我們可以通過一個簡單的例子來加深對這個問題的理解。在Java的環境下,特別是J2EE的環境下面,經典的設計思路是把數據庫的一張表視作一個類,表中的每一行都是這個類的一個具體的實例,表的每一個字段對應了類的一個變量,類一般支持Find方法,來獲取數據不同的實例。這是一種很自然的設計思路,而且可以通過CMP等技術來簡化設計的繁瑣步驟?墒,在Windows環境下,相信沒有多少人會這么做。常用的處理方法是使用記錄集(RecordSet)的方式,也就是說針對一組的記錄來進行操作,而不是單個的記錄。這些記錄可以是跨表的(使用SQL的連接),也可以是單表的。由于Windows環境下大多數的編程語言都能夠支持記錄集方式,因此編寫基于記錄集方式的程序是相當簡單的。當然,我們也可以采用J2EE平臺的編程方式,但是會導致編程量的激增,同時也難以達到預計的效果。這種平臺的差別導致了架構愿景的差別。
此外,我們注意到我們對架構的描述其實還是不夠仔細,這是非常正常的,因為隨著開發的深入,我們會不斷的完善架構的描述。例如,我們可以寫出Front Controll的類框架,寫出主要的幾個Servlet,以及他們之間的關系。這個時候,使用UML類圖會是一個不錯的選擇,實際上,我非常推崇在架構設計中大量的使用類圖。不過在實際的運作中,每個軟件團隊大多數都有自己熟悉的架構設計思路,使用何種工具并不是主要的問題。
我們從源自需求模式中,學習到架構的設計是來自于需求的,而應用于軟件全局的架構則來自于最重要的需求。還記得我們在那個模式中提到的網上寵物店的例子嗎?系統采用了MVC模式,sun的官方文檔一開始說明了為什么采用MVC模式,MVC模式解決了什么問題,然后開始分析MVC模式的幾個組成部分:Model、View、和Controll。其實,MVC中的每一個部分,在真正的代碼中,大都代表了一個子系統,但是在目前,我們就非常的清楚系統大致上會是一個什么樣子,雖然這時候它還十分的朦朧。
不要視圖在全局的架構愿景中就制定出非常細致的規劃,更不要視圖生成大量的實際代碼。因為,你的架構愿景還沒有穩定(我們在其后的穩定化的模式中將會討論穩定的問題),還沒有獲得大家的同意,也沒有經過證明。因此,從整個的開發周期來看,全局架構愿景是隨著迭代周期的進行不斷發展、修改、完善的。
我們如何確定全局架構愿景工作的完成?一般來說,你的架構設計團隊取得了一致的意見就可以結束了,如果問題域是團隊所熟悉的,一兩個小時就能夠解決問題。接下來設計團隊把架構愿景傳播到整個的開發團隊,大家形成一致的認識,不同的意見將會被反饋會來,并在本次的迭代周期(如果時間比較緊迫)或下一次的迭代周期中(如果時間比較寬松)考慮。
子模塊級、或是子問題級的架構愿景
這時候的架構愿景已經是比較明確的了,因為已經存在明確的問題域。例如界面的設計、領域模型的設計、持久層的設計等。這里的愿景制定本質上和全局的愿景制定差不多,具體的例子我們也不再舉了。但是要注意一點,你不能夠和全局愿景所違背。在操作上,全局愿景是設計團隊共同制定出來的,而子模塊級的架構愿景就可以分給設計子團隊來負責,而其審核則還是要設計團隊的共同參與。這有兩個好處,一是確保各個子模塊(子問題)間不至于相互沖突或出現空白地帶,二是每個子設計團隊可以從別人那里吸取設計經驗。
在設計時,同樣我們可以參考其它的資料,例如相關的模式、或規范(界面設計指南)。在一個有開發經驗的團隊,一般都會有開發技術的積累,這些也是可供參考的重要資料。
我們在這個層次的愿景中主要談一談子模塊(子問題)間的耦合問題。一般來說,各個子模塊間的耦合程度相對較小,例如一個MIS系統中,采購和銷售模塊的耦合度就比較小,而子問題間的耦合程度就比較大,例如權限設計、財務,這些功能將會被每個模塊使用。那么,我們就需要為子模塊(子問題)制定出合同接口(Contact Interface)。合同的意思就是說這個接口是正式的,不能夠隨意的修改,因為這個結構將會被其它的設計團隊使用,如果修改,將會對其它的團隊產生無法預計的影響。合同接口的制定、修改都需要設計團隊的通過。此外,系統中的一些全局性的子問題最好是提到全局愿景中考慮,例如在源自需求模式中提到的信貸帳務的例子中,我們就把一個利息計算方式的子問題提到了全局愿景中。
代碼級的愿景
嚴格的說這一層次的愿景已經不是真正的愿景,而是具體設計了。但是我們為了保證對架構設計理解的完整性,還是簡單的討論一下。這一個層次的愿景一般可以使用類圖、接口來表示。但在類圖中,你不需要標記出具體的屬性、操作,你只需要規定出類的職責以及類之間的相互關系就可以了。該層次愿景的審核需要設計子團隊的通過。
而設計細分到這個粒度上,執行愿景設計的開發人員可能就只有一兩個左右。但是比較重要的工作在于問題如何分解和如何歸并。分解主要是從兩個維度來考慮,一個是問題大小維,一個是時間長短維。也就是說,你(設計子團隊負責人)需要把問題按大小和解決時間的長短分解為更細的子問題,交給不同的開發人員。然后再把開發人員提出的解決方法組合起來。
架構愿景的形成過程
架構愿景的形成的源頭是需求,需要特別指出的是,這里的需求主要是那些針對系統基本面的需求。比如說,系統的特點是一個交互式系統,還是一個分布式系統。這些需求將會影響到架構愿景的設計。在收集影響架構愿景的各項需求之后,按照需求的重要性來設計架構愿景。
架構愿景的設計并不需要很復雜的過程,也不需要花費很多的時間。我們已經提過,架構遠景的主要目的就是為了能夠在開發團隊中傳播設計思路,因此,架構愿景包括基本的設計思路和基本的設計原則。
值得注意的是,架構遠景可能會有多種的視角,下文討論了一種設計模式的視角。但是實際設計中還可能會基于數據庫來設計架構愿景。但在企業信息系統的設計中,我推薦使用領域類的設計,也就是下文中討論的例子。
架構愿景設計好之后,問題的焦點就轉到如何傳播架構愿景上來,為了達到在開發團隊中取得統一設計意圖的效果,可以考慮援引團隊設計模式。除此之外,針對性的項目前期培訓也會是一種有效的做法。
使用架構模式
架構模式也是一種很好的架構愿景設計思路的來源。隨著對設計模式的研究的深入,人們發現其中的一些設計模式可以擴展、或變化為軟件設計的基礎。在這個基礎上再實現更多的設計,這些模式就形成了架構模式。當然,不同的軟件,它們的架構模式也是不一樣的。在《Applying Pattern》一文中,有一個很典型的架構愿景的例子:
假設我們需要設計分布式的交互式系統。分布式系統和交互式系統都有特定的架構模式,前者為Broker模式,后者為MVC模式。首先我們先要根據系統的特點的重要程度來排列模式的順序。這里假設需求中分布式特性更重要一些。那么我們首先選擇Broker模式作為架構的基本模式:
再考慮交互式的特點,根據MVC模式的特點,我們需要從目前的基本架構中識別出Model、Controller、以及View。Model和View都很簡單,分別分布在上圖中的Server和Client中。而Controller則有兩種的選擇,假設這里的Controller部署在客戶端,上圖則演化為下圖:
這樣,基礎的架構愿景就已經出現了。如果我們還有更多的需求,還可以繼續改進。但是,記住一點,架構愿景不要過于復雜。正如我們在上一節中所討論的,這里我們雖然是基于設計模式來討論架構愿景,但是實際中還有很多從其它的視角來看待架構愿景的。至于要如何選擇架構愿景的視角,關鍵的還是在于需求的理解。
(待續)
作者簡介:
林星,辰訊軟件工作室項目管理組資深項目經理,有多年項目實施經驗。辰訊軟件工作室致力于先進軟件思想、軟件技術的應用,主要的研究方向在于軟件過程思想、Linux集群技術、OO技術和軟件工廠模式。您可以通過電子郵件 iamlinx@21cn.com 和他聯系。
文章來源于領測軟件測試網 http://www.kjueaiud.com/