架構(gòu)的結(jié)構(gòu)和視角
回顧在上一小節(jié)中有介紹公给,軟件系統(tǒng)其實(shí)就是一系列結(jié)構(gòu)的集合,但是蜘渣,尤其是現(xiàn)代的系統(tǒng)通常都是由許多結(jié)構(gòu)組成的淌铐,從一開(kāi)始就想掌握一個(gè)系統(tǒng)的全部細(xì)節(jié)是很復(fù)雜的一件事情,這時(shí)候就需要從不同的視角(view)來(lái)剖析蔫缸,達(dá)到簡(jiǎn)化問(wèn)題的目的腿准。
結(jié)構(gòu)和視圖
- 視圖(view)是對(duì)結(jié)構(gòu)(structure)中具有代表意義的部分元素和關(guān)系進(jìn)行抽取,也可以說(shuō)拾碌,視圖是對(duì)結(jié)構(gòu)的精簡(jiǎn)吐葱。
- 通常,架構(gòu)師設(shè)計(jì)結(jié)構(gòu)校翔,但是真正記錄在文檔里的是這個(gè)結(jié)構(gòu)的精簡(jiǎn)版——視圖弟跑。
三種結(jié)構(gòu)
上一節(jié)大概說(shuō)過(guò),組成架構(gòu)的結(jié)構(gòu)類型大概有三種:模塊結(jié)構(gòu)展融,組件-連接件結(jié)構(gòu)窖认,分配結(jié)構(gòu)豫柬。
-
模塊結(jié)構(gòu)
- 模塊結(jié)構(gòu)更多的是對(duì)系統(tǒng)靜態(tài)的劃分,每一個(gè)模塊都有自己特定的功能扑浸,一般不會(huì)去考慮在執(zhí)行過(guò)程中那些交互式響應(yīng)烧给。
- 模塊視圖回答了以下問(wèn)題
- 給每一個(gè)模塊分配的最主要的功能是什么?
- 一個(gè)模塊可以使用哪些該模塊之外的元素喝噪?
- 實(shí)際會(huì)使用或者依賴哪些其它的軟件?
- 模塊之間的關(guān)系础嫡,泛化?繼承酝惧?
- 當(dāng)分配給模塊的功能發(fā)生改變時(shí)會(huì)對(duì)整個(gè)系統(tǒng)產(chǎn)生哪些影響榴鼎?-作為擴(kuò)展
-
組件-連接件結(jié)構(gòu)
- 與模塊結(jié)構(gòu)相反,組件-連接件結(jié)構(gòu)更多的是對(duì)系統(tǒng)運(yùn)行過(guò)程中的劃分晚唇,組件(component)可能是服務(wù)器巫财,客戶端等,連接件(connector)作為組件間的連接機(jī)制可能是回調(diào)函數(shù)哩陕,異步處理等等平项。
- 組件-連接件視圖可以幫助我們回答以下幾個(gè)問(wèn)題
- 在運(yùn)行過(guò)程中的主要的組件是什么,以及它們之間是怎樣交互的?
- 共享數(shù)據(jù)的存儲(chǔ)問(wèn)題
- 系統(tǒng)中的哪些部分是冗余的?
- 在系統(tǒng)中數(shù)據(jù)是怎樣處理的悍及?
- 系統(tǒng)中的哪些部分是可以并行執(zhí)行的闽瓢?
- 系統(tǒng)的架構(gòu)能否在執(zhí)行過(guò)程中進(jìn)行改變,如果可以心赶,具體怎么實(shí)現(xiàn)扣讼?
- 系統(tǒng)運(yùn)行中的屬性,比如性能缨叫,安全椭符,可執(zhí)行性等等-作為擴(kuò)展
-
分配結(jié)構(gòu)
- 就像前面說(shuō)的,軟件系統(tǒng)其實(shí)是有結(jié)構(gòu)的弯汰,但是對(duì)于底層的硬件艰山,比如CPU,文件系統(tǒng)咏闪,網(wǎng)絡(luò)等等這些是沒(méi)有結(jié)構(gòu)的曙搬,分配結(jié)構(gòu)主要就是把有結(jié)構(gòu)的軟件元素映射到外部環(huán)境中。
- 分配視圖幫助我們回答以下問(wèn)題:
- 軟件元素主要運(yùn)行在什么處理器上鸽嫂?
- 元素在運(yùn)行構(gòu)建和測(cè)試過(guò)程中存儲(chǔ)在哪個(gè)目錄的哪個(gè)文件里纵装?
- 軟件元素和開(kāi)發(fā)團(tuán)隊(duì)之間的關(guān)系
結(jié)構(gòu)作為切入點(diǎn)
每一個(gè)結(jié)構(gòu)都可以推出一些相關(guān)的質(zhì)量屬性,比如:
- 模塊的使用結(jié)構(gòu)据某,反映了模塊之間的相互依賴調(diào)用橡娄,該結(jié)構(gòu)對(duì)系統(tǒng)的可擴(kuò)展性有很大的影響。
- 并發(fā)結(jié)構(gòu)癣籽,反映了系統(tǒng)內(nèi)部的可并發(fā)性挽唉,該結(jié)構(gòu)對(duì)系統(tǒng)是否會(huì)因?yàn)橘Y源的占有進(jìn)入死鎖狀態(tài)或者出現(xiàn)性能上的瓶頸有很大影響滤祖。
- 部署結(jié)構(gòu),對(duì)最終的系統(tǒng)的性能瓶籽,可用性和安全性有很大影響匠童。
每一個(gè)結(jié)構(gòu)都給架構(gòu)提供了一個(gè)不同的設(shè)計(jì)切入點(diǎn),所以合理的設(shè)計(jì)結(jié)構(gòu)可以讓系統(tǒng)擁有相應(yīng)的好的屬性塑顺。
一些有用的模塊結(jié)構(gòu)
- 分解結(jié)構(gòu)(Decomposition structure)
- 模塊之間是' is-a-submodule-of '的關(guān)系汤求,也就是模塊一直被分解直到最容易被理解為止,這些結(jié)構(gòu)中的模塊在開(kāi)始設(shè)計(jì)的時(shí)候是相同的严拒,隨著架構(gòu)師列舉出軟件應(yīng)該實(shí)現(xiàn)的功能扬绪,就會(huì)把這些功能分配給不同的模塊來(lái)滿足后序的設(shè)計(jì)和最終的實(shí)現(xiàn)。模塊會(huì)有相應(yīng)的產(chǎn)出裤唠,如結(jié)構(gòu)挤牛,代碼,測(cè)試計(jì)劃等等巧骚。結(jié)構(gòu)模型通過(guò)把可能出現(xiàn)的改變局部話來(lái)保證了系統(tǒng)的可修改性赊颠,變更只會(huì)在一小部分的模型中出現(xiàn)格二。這個(gè)結(jié)構(gòu)通常被用于開(kāi)發(fā)系統(tǒng)的基礎(chǔ)部分劈彪,包括文檔的架構(gòu),項(xiàng)目的集成和測(cè)試方案顶猜。分解結(jié)構(gòu)中繼續(xù)細(xì)化的單元被稱為"片段"或者"子系統(tǒng)"沧奴。
- 使用結(jié)構(gòu)(use structure)
- 在這個(gè)重要但是經(jīng)常被忽視的結(jié)構(gòu)中,單元同樣表示模塊或者是類长窄,單元之間用通過(guò)使用關(guān)系連接滔吠,使用關(guān)系是對(duì)依賴關(guān)系的一種特化。一個(gè)軟件單元需要調(diào)用另一個(gè)軟件單元的某一個(gè)函數(shù)挠日,來(lái)達(dá)到自己的功能目標(biāo)疮绷。使用結(jié)構(gòu)由于可以使系統(tǒng)被擴(kuò)展和添加功能或者提取系統(tǒng)有用的核心功能,通常被用于那些工程系統(tǒng)嚣潜。
- 層結(jié)構(gòu)(layer structure)
- 在這個(gè)結(jié)構(gòu)中冬骚,模塊被稱為層,一個(gè)層可以被視為一個(gè)通過(guò)一個(gè)接口提供的一系列緊密結(jié)合的服務(wù)的虛擬機(jī)懂算。層與層之間的調(diào)用是有嚴(yán)格的規(guī)定的只冻,一個(gè)層只允許使用和它鄰接且在它下面的那個(gè)層。層結(jié)構(gòu)可以增加系統(tǒng)的可移植性和跨平臺(tái)的能力计技。
- 類/泛化結(jié)構(gòu)(Class/generalization structure)
- 在這個(gè)結(jié)構(gòu)中的模塊單元被稱為是類喜德,模塊之間的關(guān)系可以是繼承或者實(shí)例化。這個(gè)視圖產(chǎn)生一系列具有相近行為或者能力和參數(shù)的不同的單元垮媒,類結(jié)構(gòu)允許一個(gè)單元去重用另一單元或者在原來(lái)單元的基礎(chǔ)上增加功能舍悯,如果存在關(guān)于這個(gè)項(xiàng)目的某個(gè)文檔是按照面向?qū)ο蠓治龊驮O(shè)計(jì)的航棱,那么大多數(shù)都是類結(jié)構(gòu)。
- 數(shù)據(jù)結(jié)構(gòu)
- 數(shù)據(jù)模型用術(shù)語(yǔ)數(shù)據(jù)實(shí)體和它們之間的關(guān)系描述了靜態(tài)的信息結(jié)構(gòu)萌衬,比如丧诺,有些關(guān)系可能會(huì)強(qiáng)制規(guī)定一個(gè)客戶必須擁有一個(gè)以上的賬戶等等。
一些有用的C&C結(jié)構(gòu)
組件-連接件結(jié)構(gòu)反映了系統(tǒng)的實(shí)時(shí)視圖奄薇,在這些結(jié)構(gòu)中驳阎,上述的模塊都被編譯為可執(zhí)行的形式,所有的組件-連接件結(jié)構(gòu)和基于模塊的結(jié)構(gòu)是正交關(guān)系并用于處理正在運(yùn)行系統(tǒng)的動(dòng)態(tài)層面馁蒂。組件-連接件間的關(guān)系顯示了組件和連接件是如何切合在一起的呵晚,這個(gè)關(guān)系被稱為附件(attachment),連接件可以只是最普通的結(jié)構(gòu)比如'調(diào)用'沫屡,有用的C&C結(jié)構(gòu)包括以下:
- 服務(wù)結(jié)構(gòu)(Service structure)
- 結(jié)構(gòu)中的單元被稱為是服務(wù)饵隙,這些服務(wù)通過(guò)服務(wù)協(xié)的機(jī)制比如SOAP進(jìn)行交互操作。服務(wù)結(jié)構(gòu)是一種很重要的結(jié)構(gòu)沮脖,它使得我們可以異步或者獨(dú)立的對(duì)組件進(jìn)行開(kāi)發(fā)金矛。
- 并發(fā)結(jié)構(gòu)(Concurrency structure)
- 對(duì)于這個(gè)組件-連接件結(jié)構(gòu)可以使架構(gòu)師確定并發(fā)的幾率并且明確可能發(fā)生資源沖突的地方。該結(jié)構(gòu)中的單元稱為組件勺届,連接件是組件間的溝通機(jī)制驶俊,組件按照一定的規(guī)則被整理在不同的邏輯線程(logical thread)中,一個(gè)邏輯線程是一系列的計(jì)算過(guò)程并且在后續(xù)的設(shè)計(jì)過(guò)程中該邏輯線程可以被分配到單獨(dú)一個(gè)物理線程中免姿,并發(fā)結(jié)構(gòu)在設(shè)計(jì)過(guò)程的初期被使用饼酿,用于發(fā)現(xiàn)和識(shí)別并發(fā)執(zhí)行中的需求。
一些有用的分配結(jié)構(gòu)
分配結(jié)構(gòu)定義了那些屬于C&C結(jié)構(gòu)和模塊結(jié)構(gòu)的元素怎樣映射到非軟件的事物上,比如硬件,團(tuán)隊(duì)鹿驼,文件系統(tǒng)等,有用的分配結(jié)構(gòu)包括:
- 部署結(jié)構(gòu)(Deployment structure)
- 部署結(jié)構(gòu)展示了軟件是如何被分配到硬件進(jìn)程和通信部件上的药版,該結(jié)構(gòu)中的元素包括軟件元素(通常是組件-連接件中的一個(gè)進(jìn)程),硬件實(shí)體喻犁,和通信連接槽片,元素間的關(guān)系是 allocated-to,表明了軟件元素處于哪一個(gè)物理單元之上并且如果分配是動(dòng)態(tài)的還包括 migrates-to 的關(guān)系株汉,這個(gè)結(jié)構(gòu)可以被用于解釋性能筐乳,數(shù)據(jù)集成,安全和可用性乔妈,在分布式和并行式系統(tǒng)中非常有用蝙云。
- 實(shí)現(xiàn)結(jié)構(gòu)(Implementation structure)
- 實(shí)現(xiàn)結(jié)構(gòu)展示了軟件元素(通常是模塊)在系統(tǒng)開(kāi)發(fā),集成或者配置控制環(huán)境中是如何映射到文件結(jié)構(gòu)中的路召,這對(duì)開(kāi)發(fā)和構(gòu)建過(guò)程的管理來(lái)說(shuō)非常重要勃刨。
- 工作分配結(jié)構(gòu)(Work assignment structure)
- 工作分配結(jié)構(gòu)把實(shí)現(xiàn)和集成模塊的任務(wù)以團(tuán)隊(duì)為單位進(jìn)行分配波材,有了結(jié)構(gòu)分配圖使得誰(shuí)做什么工作變的清晰,同時(shí)架構(gòu)師知道每一個(gè)團(tuán)隊(duì)的專長(zhǎng)身隐,在大型的多參與者的開(kāi)發(fā)項(xiàng)目中廷区,工作分配結(jié)構(gòu)通常是將功能單元只分配給一個(gè)團(tuán)隊(duì)實(shí)現(xiàn),其它需要開(kāi)發(fā)相同功能的團(tuán)隊(duì)進(jìn)行功能的調(diào)用即可贾铝,而不是讓每一個(gè)需要該功能的團(tuán)隊(duì)把它都開(kāi)發(fā)一遍隙轻,這個(gè)結(jié)構(gòu)同樣規(guī)定可團(tuán)隊(duì)之間的溝通方式,比如垢揩,郵件...
將結(jié)構(gòu)互相之間進(jìn)行聯(lián)系
每一個(gè)結(jié)構(gòu)都提供了一種不同的設(shè)計(jì)和處理系統(tǒng)的觀點(diǎn)玖绿,并且從每一個(gè)結(jié)構(gòu)自身出發(fā)它們都是有用且有效的,盡管每一個(gè)結(jié)構(gòu)都分別對(duì)應(yīng)了系統(tǒng)的不同方面叁巨,但是這些結(jié)構(gòu)本身并不是孤立的斑匪。某一個(gè)結(jié)構(gòu)中的元素可能會(huì)和其它結(jié)構(gòu)中的元素相聯(lián)系,所以我們需要對(duì)這些聯(lián)系作相應(yīng)的解釋锋勺,比如蚀瘸,在分解結(jié)構(gòu)中的一個(gè)模塊可能會(huì)被解釋為一個(gè)組件-連接件,一個(gè)組件-連接件中的一部分庶橱,或者是一個(gè)組件-連接件中的一些組件贮勃,這些反應(yīng)了系統(tǒng)在運(yùn)行過(guò)程中的自我改變的能力,總的來(lái)說(shuō)悬包,結(jié)構(gòu)與結(jié)構(gòu)之間的映射是多對(duì)多的衙猪。
如圖1.2所示是一個(gè)有關(guān)兩個(gè)結(jié)構(gòu)之間是怎樣進(jìn)行聯(lián)系的簡(jiǎn)單的例子,圖的左邊顯示了一個(gè)小型CS系統(tǒng)的模塊分解圖(module decomposition view)布近,在這個(gè)系統(tǒng)中,有兩個(gè)模塊必須被實(shí)現(xiàn)丝格,分別是客戶端軟件和服務(wù)器端軟件撑瞧,圖的右邊顯示了這個(gè)CS架構(gòu)系統(tǒng)的組件-連接件的視圖,從圖中也可以看出在運(yùn)行過(guò)程中有十個(gè)客戶端和服務(wù)器相連接显蝌,所以這個(gè)小的CS架構(gòu)的系統(tǒng)有兩個(gè)模塊和十一個(gè)組件(十個(gè)連接件)预伺。
雖然在圖中明顯的可以看出在分解結(jié)構(gòu)和CS結(jié)構(gòu)中的元素是非常相似的,但是這兩個(gè)視圖的用途卻不盡相同曼尊,比如酬诀,右邊的視圖可以被用于性能的分析,瓶頸的預(yù)測(cè)和對(duì)網(wǎng)絡(luò)流量的管理骆撇,如果使用左邊的視圖來(lái)做以上事情是十分困難的瞒御。
在個(gè)人的項(xiàng)目中有時(shí)侯會(huì)決定一個(gè)主要的結(jié)構(gòu),并在有可能的情況下神郊,用該主要結(jié)構(gòu)來(lái)描述其它結(jié)構(gòu)肴裙,通常將主要結(jié)構(gòu)規(guī)定為模塊的分解結(jié)構(gòu)趾唱,這樣做是因?yàn)槟K的分解結(jié)構(gòu)跟有利于衍生出整個(gè)項(xiàng)目的結(jié)構(gòu),因?yàn)榉纸饨Y(jié)構(gòu)反映了開(kāi)發(fā)團(tuán)隊(duì)的結(jié)構(gòu)蜻懦,在有些其他項(xiàng)目中甜癞,主要的結(jié)構(gòu)也可能是C&C結(jié)構(gòu),用來(lái)顯示系統(tǒng)的功能或者實(shí)現(xiàn)的主要質(zhì)量屬性宛乃。
越少越好
不是所有的系統(tǒng)都需要考慮許多的架構(gòu)結(jié)構(gòu)悠咱,系統(tǒng)越龐大,結(jié)構(gòu)間顯著的差異就比較多征炼,但對(duì)于小系統(tǒng)來(lái)說(shuō)乔煞,結(jié)構(gòu)的數(shù)量是相對(duì)比較少的,通常只是處理一個(gè)組件-連接件結(jié)構(gòu)柒室。如果在小系統(tǒng)中只有一個(gè)進(jìn)程渡贾,那么進(jìn)程結(jié)構(gòu)就可以相應(yīng)的退化為一個(gè)節(jié)點(diǎn)并且不需要明確的表示在設(shè)計(jì)中。如果小系統(tǒng)只是基于一個(gè)處理器實(shí)現(xiàn)雄右,那么對(duì)應(yīng)的部署結(jié)構(gòu)也不需要被考慮空骚。總的來(lái)說(shuō)擂仍,當(dāng)且僅當(dāng)一個(gè)結(jié)構(gòu)會(huì)給開(kāi)發(fā)過(guò)程帶來(lái)好處囤屹,比如簡(jiǎn)化開(kāi)發(fā)或者維持開(kāi)銷時(shí),該結(jié)構(gòu)才會(huì)被設(shè)計(jì)并記錄逢渔。
選擇哪一個(gè)結(jié)構(gòu)
我們已經(jīng)對(duì)許多有用的結(jié)構(gòu)架構(gòu)進(jìn)行了簡(jiǎn)單明確的描述肋坚,但是在實(shí)際開(kāi)發(fā)過(guò)程中,應(yīng)該選擇哪一個(gè)架構(gòu)肃廓,哪一個(gè)架構(gòu)應(yīng)該被記錄智厌,當(dāng)然不是所有的,對(duì)于現(xiàn)在來(lái)說(shuō)盲赊,只是根據(jù)架構(gòu)的可用性和對(duì)系統(tǒng)重要質(zhì)量屬性的影響進(jìn)行選擇铣鹏,再挑選出一個(gè)表現(xiàn)最好的架構(gòu)進(jìn)行使用。