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