屬性驅(qū)動(dòng)設(shè)計(jì)是目前最全面最廣泛使用的有文檔記錄的軟件架構(gòu)設(shè)計(jì)方法,簡稱ADD。在ADD第一次出現(xiàn)時(shí),他是一個(gè)特別側(cè)重于質(zhì)量屬性,并且通過創(chuàng)建軟件架構(gòu)的結(jié)構(gòu)方式來實(shí)現(xiàn)他們,通過視圖來表示他們的設(shè)計(jì)方法。它把軟件架構(gòu)分析和文檔作為設(shè)計(jì)過程的一個(gè)重要組成部分。在ADD中,設(shè)計(jì)活動(dòng)包括提煉早期設(shè)計(jì)迭代過程中創(chuàng)建的草圖來產(chǎn)生一個(gè)更詳細(xì)的架構(gòu),并不斷對(duì)設(shè)計(jì)進(jìn)行評(píng)估。
在ADD2.0發(fā)布時(shí),對(duì)于如何將質(zhì)量屬性和設(shè)計(jì)選擇相關(guān)關(guān)聯(lián)起來非常有用,但仍舊有一些缺點(diǎn):
- ADD2.0指導(dǎo)架構(gòu)師使用并將策略和模式組合在一起以實(shí)現(xiàn)令人滿意的質(zhì)量屬性場(chǎng)景,但是模式和策略比較抽象,沒有解釋如何去映射成具體的技術(shù)
2.ADD2.0在敏捷開發(fā)之前發(fā)布,所以沒有關(guān)于敏捷開發(fā)環(huán)境的指導(dǎo)。 - 沒有提供如何開始設(shè)計(jì)過程的指導(dǎo)。
- 沒有處理一些架構(gòu)關(guān)注點(diǎn)、考慮不同的設(shè)計(jì)目標(biāo)。
。。。。
在ADD3.0中,以上的這些都解決了,對(duì)于敏捷開發(fā)中,ADD3.0推廣的是快速設(shè)計(jì)迭代,在每個(gè)迭代盡量做出少的設(shè)計(jì)決策,可能是一個(gè)實(shí)現(xiàn)的重建增量。
在ADD3.0中推廣了使用參考架構(gòu),并與設(shè)計(jì)概念目錄配對(duì),該目錄中包括一個(gè)各種戰(zhàn)術(shù),模式,框架,參考架構(gòu)和技術(shù)的選集。
在看這篇文章之前,里面有很多專業(yè)性名詞解釋,建議先看下這篇文章,對(duì)一些架構(gòu)相關(guān)和屬性驅(qū)動(dòng)設(shè)計(jì)相關(guān)的概念能有一個(gè)入門性的認(rèn)識(shí),方便后面的學(xué)習(xí):
ADD3.0屬性驅(qū)動(dòng)設(shè)計(jì)之基礎(chǔ)
屬性驅(qū)動(dòng)設(shè)計(jì)的架構(gòu)設(shè)計(jì)過程

1.步驟一: 評(píng)審輸入
首先需要確保設(shè)計(jì)流程的輸入是可用且正確的,先確認(rèn)設(shè)計(jì)目的是否符合設(shè)計(jì)的類型,確保設(shè)計(jì)過程中其他的屬性驅(qū)動(dòng)因子也是可用的,最后,如果是設(shè)計(jì)一個(gè)綠地系統(tǒng),還需要已經(jīng)存在的架構(gòu)設(shè)計(jì)的輸入存在是否合理。
(注: 架構(gòu)驅(qū)動(dòng)因子包含: 設(shè)計(jì)目的、質(zhì)量屬性、主要功能、架構(gòu)關(guān)注點(diǎn)、約束條件等等,詳情我后面會(huì)說)
驅(qū)動(dòng)因子成了架構(gòu)設(shè)計(jì)待辦列表的一部分,需要用他們來完成不同的迭代目標(biāo)。
2.步驟二: 通過選擇驅(qū)動(dòng)因子(架構(gòu))建立迭代目標(biāo)
根據(jù)使用的開發(fā)模型去選擇設(shè)計(jì)的回合。
如果是迭代開發(fā)模型,設(shè)計(jì)回合指在開發(fā)周期內(nèi)所執(zhí)行的架構(gòu)設(shè)計(jì)活動(dòng),如果是瀑布模型,設(shè)計(jì)回合指代的是全套架構(gòu)設(shè)計(jì)活動(dòng)。通過一個(gè)或者多個(gè)回合,產(chǎn)生一個(gè)符合已建立設(shè)計(jì)目的架構(gòu)。
一個(gè)設(shè)計(jì)回合需要在一系列的設(shè)計(jì)迭代中進(jìn)行,每一個(gè)迭代著重完成一個(gè)目標(biāo),特別是滿足驅(qū)動(dòng)因子的目標(biāo)。舉個(gè)例子: 一個(gè)迭代的目標(biāo)可能是創(chuàng)建源自元素的結(jié)構(gòu),這些元素會(huì)支持特殊的性能場(chǎng)景,或者啟動(dòng)一個(gè)即將完成的用例。
3.步驟三: 選擇一個(gè)或者多個(gè)系統(tǒng)元素來細(xì)化
(注: 這里的元素是指軟件模塊、整個(gè)軟件系統(tǒng)包含多少個(gè)元素或者說子模塊,電商軟件系統(tǒng): 訂單、庫存、支付、前臺(tái)、用戶等等元素)
需要滿足驅(qū)動(dòng)因子需要產(chǎn)生一個(gè)或者多個(gè)架構(gòu)結(jié)構(gòu),這些結(jié)構(gòu)是由具有內(nèi)在關(guān)聯(lián)的元素組成的,并且這些元素通常是經(jīng)過細(xì)化前在之前的迭代中確定的元素獲得的。
細(xì)化就是分解成細(xì)?;脑?、組合成粗粒度的元素或者對(duì)之前確定好的元素進(jìn)行細(xì)化。
4.步驟四: 選擇一個(gè)或者多個(gè)設(shè)計(jì)概念(就是架構(gòu)設(shè)計(jì)模式)以滿足選中的驅(qū)動(dòng)因子.
架構(gòu)設(shè)計(jì)模式包括結(jié)構(gòu)模式: 分層設(shè)計(jì)、域?qū)ο笤O(shè)計(jì)。接口分區(qū):顯示接口,代理。 基于高并發(fā)得設(shè)計(jì): 半異步/半同步設(shè)計(jì)。后面會(huì)詳細(xì)介紹。
5.步驟五:實(shí)例化架構(gòu)元素、分配職責(zé)和定義接口
選擇好了一個(gè)或者多個(gè)設(shè)計(jì)概念,就要另作一個(gè)設(shè)計(jì)決策了,包括所選擇的實(shí)例化元素的設(shè)計(jì)概念。如果選擇分層,需要決定分多少層,在這里例子中,這些分層就是實(shí)例化后的元素,某些情況下,實(shí)例化是可以配置的。
在實(shí)例化元素之后,需要給每個(gè)元素分配職責(zé)。舉個(gè)例子: 在據(jù)于網(wǎng)絡(luò)的企業(yè)級(jí)系統(tǒng)中,通常有三層:表示層、業(yè)務(wù)層、數(shù)據(jù)層。
實(shí)例化元素只是一個(gè)任務(wù),這個(gè)任務(wù)通過開展創(chuàng)建架構(gòu)以滿足一個(gè)驅(qū)動(dòng)因子或者一個(gè)關(guān)注點(diǎn)。已經(jīng)被實(shí)例化后的元素也需要被關(guān)注起來,一遍這些元素之間可以互相配合。通過接口來實(shí)現(xiàn)交互。
6步驟六: 草擬視圖和記錄設(shè)計(jì)決策
到了這一步,已經(jīng)完成了該迭代中所執(zhí)行的設(shè)計(jì)活動(dòng)了??赡苣氵€沒有采用任何行動(dòng)來確保結(jié)果視圖能夠被保留。你創(chuàng)建好的視圖肯定不是完整的,在隨后的迭代中這些圖可能還需要重新被審視和細(xì)化。通常這樣做是為了調(diào)整其他設(shè)計(jì)決策產(chǎn)生的元素,這些設(shè)計(jì)決策還需要支持其他的驅(qū)動(dòng)因子,這個(gè)就解釋了,我們?cè)贏DD方法中,強(qiáng)調(diào)手稿,代表創(chuàng)建初期。
7:步驟七: 分析當(dāng)前設(shè)計(jì)、評(píng)審迭代目標(biāo)、實(shí)現(xiàn)設(shè)計(jì)目的
目前已經(jīng)創(chuàng)建好了部分設(shè)計(jì),此時(shí)已經(jīng)可以得到這個(gè)迭代設(shè)計(jì)建立的目標(biāo)。徐奧確保這個(gè)目標(biāo)是一個(gè)好想法,可以得到項(xiàng)目利益相關(guān)者的認(rèn)同,避免否定,導(dǎo)致返工。此時(shí)可以自己繼續(xù)展開分析或者找人幫助評(píng)審。
一旦在迭代中執(zhí)行的設(shè)計(jì)進(jìn)行了分析,此時(shí)你就可以根據(jù)既定的目標(biāo)來評(píng)審你的架構(gòu)狀態(tài)。這意味著,你已經(jīng)進(jìn)行了足夠的設(shè)計(jì)迭代,已滿足與設(shè)計(jì)回合相關(guān)的驅(qū)動(dòng)因子,以及考慮設(shè)計(jì)目標(biāo)是否已經(jīng)實(shí)現(xiàn)了,或者在未來項(xiàng)目增量中,是否需要額外的回合。
最后一步: 按需迭代
理想狀態(tài)下,對(duì)每一個(gè)被稱為輸入組成之一的驅(qū)動(dòng)因子,都要執(zhí)行額外的迭代,并重復(fù)執(zhí)行步驟2-7.通常情況下,這樣的迭代不太可能出現(xiàn),因?yàn)闀r(shí)間或資源的限制,會(huì)迫使你停止設(shè)計(jì)活動(dòng)。
對(duì)于是否需要更多的迭代,可以讓風(fēng)險(xiǎn)來評(píng)估。怎么說呢?我們至少找到更高優(yōu)先級(jí)的驅(qū)動(dòng)因子,理論上,應(yīng)該確保關(guān)鍵驅(qū)動(dòng)因子是被滿足的,或者至少設(shè)計(jì)了足夠好的滿足驅(qū)動(dòng)因子,最后實(shí)施時(shí),能夠在每個(gè)項(xiàng)目迭代中,執(zhí)行一個(gè)設(shè)計(jì)回合。第一回合把重點(diǎn)放在定位驅(qū)動(dòng)因子上,隨后再為其他回合指定設(shè)計(jì)決策。
根據(jù)系統(tǒng)設(shè)計(jì)類型遵循設(shè)計(jì)路線圖
一般來說,軟件系統(tǒng)的設(shè)計(jì)分為三大類:
1. 一個(gè)成熟領(lǐng)域內(nèi)的綠地系統(tǒng)設(shè)計(jì)。

舉個(gè)例子: 比如非常常見的電商購物系統(tǒng)、CRM等企業(yè)級(jí)系統(tǒng),都是在領(lǐng)域內(nèi)很成熟的,并且常見的架構(gòu)關(guān)注點(diǎn)也總所周知,十分常見??梢园凑丈蠄D的步驟來實(shí)現(xiàn)。
最初的迭代目標(biāo)應(yīng)該是,解決建立一個(gè)初步完整的整體系統(tǒng)體系架構(gòu)的常見關(guān)注點(diǎn),是一個(gè)瀏覽器到服務(wù)器的一個(gè)應(yīng)用程序或者移動(dòng)端到服務(wù)端。這些選擇會(huì)讓你建立不同的架構(gòu)解決方案,并且這些解決方方案將有不同的實(shí)現(xiàn)驅(qū)動(dòng)因子。
具體而言,為了實(shí)現(xiàn)設(shè)計(jì)目標(biāo),,需要選擇設(shè)計(jì)概念,會(huì)選擇一個(gè)或多個(gè)參考架構(gòu)和部署模式,還有一些外部開發(fā)組件比如spring框架等。
在第一期迭代,需要評(píng)審所有的驅(qū)動(dòng)因子來選擇設(shè)計(jì)概念,也需要注意約束條件和質(zhì)量參數(shù)。
接著的迭代目標(biāo),應(yīng)該是識(shí)別那些支持主要功能的結(jié)構(gòu),對(duì)功能進(jìn)行分配,一旦功能被分配好了,支持功能的元素可以在之后的迭代階段,支持與這些功能關(guān)聯(lián)的質(zhì)量參數(shù)。例如選擇一個(gè)web應(yīng)用程序參考體系結(jié)構(gòu),支持的用例可能需要識(shí)別模塊,這些模塊貫穿在與參考架構(gòu)關(guān)聯(lián)的不同分層中,最后,在這一點(diǎn)上,也應(yīng)該考慮哪些與模塊相關(guān)的功能分配,要分配到開發(fā)團(tuán)隊(duì)中去。
之后的迭代目標(biāo),應(yīng)該是完善細(xì)化之前創(chuàng)建的結(jié)構(gòu),以完全解決剩余的驅(qū)動(dòng)因子,特別是質(zhì)量屬性。
2. 一個(gè)新領(lǐng)域內(nèi)的綠地系統(tǒng)設(shè)計(jì)。
在新興領(lǐng)域的例子中,比較有挑戰(zhàn)性的是建立一個(gè)精確的路線圖。這塊的設(shè)計(jì)路線圖,沒辦法詳細(xì)說明,還是基于屬性驅(qū)動(dòng)設(shè)計(jì)的思路:
迭代的目標(biāo)主要還是不斷完善和細(xì)化以前創(chuàng)建的結(jié)構(gòu),以充分解決這些驅(qū)動(dòng)因子。
3.對(duì)現(xiàn)有系統(tǒng)的更改設(shè)計(jì)(棕地系統(tǒng)設(shè)計(jì))。
現(xiàn)存系統(tǒng)架構(gòu)設(shè)計(jì)的目的不同,最顯而易見的是保留,就是說在滿足新需求和修復(fù)bug的時(shí)候,需要改變現(xiàn)有的系統(tǒng)架構(gòu),我們?cè)贏DD方法的步驟三中說明了,需要選擇元素已將其分解為設(shè)計(jì)過程的一部分,首先需要確定哪些元素存在于現(xiàn)有的系統(tǒng)架構(gòu)中,從這個(gè)意義來說,在開始設(shè)計(jì)迭代之前,第一個(gè)目標(biāo),需要先對(duì)現(xiàn)有系統(tǒng)的架構(gòu)有非常清晰的認(rèn)識(shí)。
一旦你理解了元素、屬性、構(gòu)成系統(tǒng)架構(gòu)的關(guān)系,以及現(xiàn)存代碼庫的屬性,在初始設(shè)計(jì)迭代之后,就可以執(zhí)行類似于下面面對(duì)綠地系統(tǒng)的設(shè)計(jì)。
設(shè)計(jì)目標(biāo)應(yīng)該是確定和改進(jìn)結(jié)構(gòu),以滿足架構(gòu)驅(qū)動(dòng)因子,包括新的功能和質(zhì)量參數(shù),以及解決特定的架構(gòu)問題關(guān)注點(diǎn),包括新的功能和質(zhì)量參數(shù),以及解決特定的架構(gòu)問題。
如何設(shè)計(jì)和選擇設(shè)計(jì)概念
設(shè)計(jì)概念的識(shí)別是很艱難的,因?yàn)槭澜缟嫌泻芏嗟脑O(shè)計(jì)概念,可能有幾十個(gè)設(shè)計(jì)模式和外部開發(fā)組件,能夠用來解決特定的具體問題。
在設(shè)計(jì)過程中的不同環(huán)節(jié)一般需要不同類型的設(shè)計(jì)概念,比如設(shè)計(jì)成熟領(lǐng)域的綠地系統(tǒng)時(shí),有助于初步構(gòu)建系統(tǒng)設(shè)計(jì)概念類型的是參考架構(gòu)和部署模式。
隨著設(shè)計(jì)過程的進(jìn)行,將使用所有的設(shè)計(jì)概念類型: 決策,架構(gòu)和設(shè)計(jì)模式、外部開發(fā)組件。一般來說,為了解決一個(gè)特定的設(shè)計(jì)問題,都會(huì)使用各種不同的設(shè)計(jì)概念組合起來。
一旦對(duì)需要使用的設(shè)計(jì)概念有清晰的理解之后,還需要一個(gè)確認(rèn)一個(gè)替換方案---就是設(shè)計(jì)的候選方案。
在識(shí)別和選擇設(shè)計(jì)概念時(shí),也要考慮約束因子,這也是架構(gòu)驅(qū)動(dòng)因子的一部分,某些條件可能會(huì)限制你選擇特定的替換方案。
最后還需要記住,ADD這種方式只是對(duì)如何執(zhí)行設(shè)計(jì)過程提出了指導(dǎo),并不意味著能確保你做出合適的設(shè)計(jì)決策。
架構(gòu)結(jié)構(gòu)的生成
設(shè)計(jì)概念對(duì)滿足驅(qū)動(dòng)因子本身沒有幫助,除非構(gòu)建出架構(gòu)來,也就是說,需要識(shí)別并選定設(shè)計(jì)概念的元素,在ADD方法中,這個(gè)過程其實(shí)就是架構(gòu)元素實(shí)例化,建立元素與元素之間的關(guān)系,給這些元素分配不同的職責(zé).需要清楚,一個(gè)軟件系統(tǒng)應(yīng)該是由一組結(jié)構(gòu)組成的,這些結(jié)構(gòu)可以分成三大類:
1、模塊結(jié)構(gòu)
由開發(fā)期間的邏輯和靜態(tài)元素組成,如文件、模塊以及類。
2、組件和連接器結(jié)構(gòu)
由運(yùn)行時(shí)存在的動(dòng)態(tài)元素組成,如進(jìn)程和線程
3、分配結(jié)構(gòu)
由兩個(gè)軟件元素(來自于C&C結(jié)構(gòu))以及非軟件元素組成,非軟件元素一般存在于開發(fā)期間也存在
于運(yùn)行期間,如文件系統(tǒng)、硬件以及開發(fā)團(tuán)隊(duì)。
實(shí)例化設(shè)計(jì)概念時(shí),可能生成不止一個(gè)結(jié)構(gòu)。例如,在某個(gè)特定的迭代中,實(shí)例化分層模式,生成一個(gè)模塊結(jié)構(gòu)。作為實(shí)例化該模塊的一部分,選擇分層數(shù)量、層與層之間的關(guān)系,以及每一層的職責(zé),作為迭代的一部分,也可以研究場(chǎng)景是如何由元素支撐起來的,這些元素就是你剛剛確定下來的那些。例如,可以在C&C建立一個(gè)邏輯元素的實(shí)例,模擬邏輯元素交換的信息。最后要決定誰來負(fù)責(zé)實(shí)施每一層內(nèi)的模塊,稱之為分配決策。
需要以下步驟:
1. 把架構(gòu)元素實(shí)例化
架構(gòu)元素方面的實(shí)例化,取決于你正在制定的設(shè)計(jì)概念的類型:
參考架構(gòu): 在參考架構(gòu)的情況下,實(shí)例化就需要實(shí)施某些定制化,增加或者刪除某些元素。比如如果是個(gè)web應(yīng)用程序,在處理支付相關(guān)操作時(shí),需要跟一個(gè)外部應(yīng)用程序進(jìn)行通信,除了正常的MVC層之外,還需要一個(gè)集成層。
架構(gòu)和設(shè)計(jì)模式: 實(shí)例化通常涉及到由模式定義的通用結(jié)構(gòu)的轉(zhuǎn)換,轉(zhuǎn)換到特定的結(jié)構(gòu)。
部署模式:部署模式的實(shí)例化通常涉及物理元素的識(shí)別和規(guī)范,比如部署的集群的數(shù)量,負(fù)載均衡策略,算法,和副本的位置等等。
策略: 策略這個(gè)設(shè)計(jì)概念沒有特定的結(jié)果,所以需要使用其他設(shè)計(jì)概念來實(shí)例化策略,比如你選擇一種角色驗(yàn)證的安全策略,可以創(chuàng)建一個(gè)臨時(shí)編碼來實(shí)例化該策略,也可以通過安全模式或者使用外部開發(fā)安全框架來實(shí)現(xiàn)。
第二步: 劃分職責(zé)和識(shí)別屬性
通過實(shí)例化設(shè)計(jì)概念和創(chuàng)建元素時(shí),需要考慮給這些元素分配職責(zé)。比如如果是實(shí)例化分層模式并且使用傳統(tǒng)的三層時(shí),還需要考慮其中一個(gè)分層負(fù)責(zé)處理用戶交互,這是表示層,在實(shí)例化元素和分配職責(zé)時(shí),切記系統(tǒng)邊界的問題,高內(nèi)聚/低耦合的設(shè)計(jì)原則,元素需要具有高內(nèi)聚,比如通過小范圍的職責(zé)定義,還要保持低耦合,不用通過了解其他元素來實(shí)現(xiàn)業(yè)務(wù)細(xì)節(jié)。
在設(shè)計(jì)化實(shí)例概念時(shí),需要考慮另一個(gè)方面的元素的屬性,這可能包括比如一些配置的選項(xiàng),狀態(tài)性,資源管理,優(yōu)先級(jí),識(shí)別這些屬性來幫助分析和維持設(shè)計(jì)原理文檔。
最后要建立元素之間的關(guān)系
架構(gòu)創(chuàng)建還需要對(duì)元素和元素屬性之間存在的關(guān)系做出決策。然后,可以考慮分層模式。你可以決定把兩層連接起來,但是這些層,終將會(huì)分配在不同的機(jī)器上,此時(shí)你可以涉及如何進(jìn)行通信,選擇的哪種通信協(xié)議,進(jìn)行異步通信還是同步通信?這些都會(huì)對(duì)生成的具體的質(zhì)量屬性有明顯的影響,如性能等屬性。
設(shè)計(jì)過程中第五步: 定義接口
接口是我們?cè)氐耐獠靠梢妼傩?,這些元素建立了一個(gè)允許元素合作和交換信息的規(guī)范。接口有兩種類型: 內(nèi)部的和外部的。
外部接口: 正在開發(fā)的系統(tǒng)需要其他外部的其他系統(tǒng)提供的接口,以及我們提供給外部系統(tǒng)的接口。
內(nèi)部接口是設(shè)計(jì)實(shí)例化概念設(shè)計(jì)結(jié)構(gòu)產(chǎn)生的元素之間的接口,要實(shí)現(xiàn)接口間的關(guān)系和細(xì)節(jié),通常需要了解運(yùn)行時(shí)如何交換信息,這需要建模工具來理解,可以使用UML工具中的序列圖來對(duì)執(zhí)行過程中元素的交互信息進(jìn)行建模,來支持用例和質(zhì)量屬性方案,這種類型的分析也有利于識(shí)別元素間的交互關(guān)系。