軟件架構(gòu)
對于許多開發(fā)者而言,在適當(dāng)?shù)牡胤經(jīng)]有正式的架構(gòu)就開始敲代碼是一件極為普通的事情。為什么要有架構(gòu)呢?
為什么構(gòu)建軟件架構(gòu)
眾多的利益相關(guān)者
軟件系統(tǒng)必須迎合利益相關(guān)者的變化,例如業(yè)務(wù)經(jīng)理,主人,用戶和操作者。這些利益相關(guān)者都有對于系統(tǒng)的期望概念,平衡這些意圖,證明它們是如何解決的是設(shè)計(jì)系統(tǒng)的一部分。這意味著架構(gòu)牽涉處理意圖的變化和利益關(guān)系,這里面牽涉各種學(xué)問。
關(guān)系的分離
對于已制定的架構(gòu)去減少復(fù)雜度是驅(qū)使設(shè)計(jì)分離關(guān)系。架構(gòu)文本展示了所有利益相關(guān)者關(guān)心的事情通過模型化和從關(guān)聯(lián)變化的利益關(guān)系關(guān)心的事的點(diǎn)子上分離地描述架構(gòu)。這些分離描述被稱之為架構(gòu)視圖
質(zhì)量驅(qū)動(dòng)
古典的架構(gòu)設(shè)計(jì)方法通過要求函數(shù)和通過系統(tǒng)的數(shù)據(jù)流來驅(qū)動(dòng),但是當(dāng)前的視野是軟件系統(tǒng)的架構(gòu)更加接近相關(guān)它的品質(zhì)屬性例如容錯(cuò),向后兼容,可擴(kuò)展性,可利用性,維護(hù)性,可用性,安全性等等。利益相關(guān)者關(guān)心的事情常在這些品質(zhì)屬性上唄轉(zhuǎn)換到要求,這被稱之為非功能性要求,額外的功能要求,行為要求,品質(zhì)屬性要求等
再發(fā)的循環(huán)
像建筑建筑一樣,軟件架構(gòu)學(xué)科有一個(gè)發(fā)達(dá)的標(biāo)準(zhǔn)方式去實(shí)現(xiàn)再發(fā)的關(guān)心的事。這個(gè)標(biāo)準(zhǔn)方式被以在抽象的變化等級(jí)內(nèi)的變化的名字命名。一般的術(shù)語對于再發(fā)的解決方案是架構(gòu)化的風(fēng)格,引用架構(gòu),架構(gòu)樣式
概念上的完整
一個(gè)被fred介紹的術(shù)語去表示一個(gè)軟件系統(tǒng)呈現(xiàn)一個(gè)它應(yīng)該干什么,如何做的全部的視角。這個(gè)視角應(yīng)該通過它的實(shí)現(xiàn)被分離。
這就是為什么要設(shè)計(jì)軟件架構(gòu)?尤其是一個(gè)大型項(xiàng)目,你必須設(shè)計(jì)它的架構(gòu),否則當(dāng)在不停擴(kuò)展它的功能時(shí)候,你會(huì)發(fā)現(xiàn)后面完全做不下去了,真正好的架構(gòu)應(yīng)該是高內(nèi)聚,低耦合。
1,分層的模式
最為普遍的架構(gòu)樣式就是分層的模式,在其他方面聞名的N層樣式。這個(gè)樣式對于許多Java應(yīng)用而言是事實(shí)上的標(biāo)準(zhǔn),因此被許多架構(gòu)師,設(shè)計(jì)者,開發(fā)者廣為流傳。分層的模式密切地關(guān)聯(lián)著傳統(tǒng)的IT團(tuán)體和組織,這對于許多商業(yè)應(yīng)用開發(fā)而言是一個(gè)自然的選擇
1.1 模式描述
在分層的架構(gòu)模式內(nèi)的小組件被以水平式的方式組織。每層在應(yīng)用內(nèi)呈現(xiàn)特定的角色。入呈現(xiàn)邏輯或業(yè)務(wù)邏輯。盡管分層架構(gòu)的模式是不指定層的類型和數(shù)量。大多數(shù)分層的架構(gòu)組成了四個(gè)標(biāo)準(zhǔn)層次:展示,業(yè)務(wù),持久和數(shù)據(jù)庫。在有些事件中,業(yè)務(wù)層和持久層被結(jié)合進(jìn)入一個(gè)單一的業(yè)務(wù)層。通常地持久邏輯在業(yè)務(wù)層小組件內(nèi)插入。因此,較小的應(yīng)用只有三層,較大的復(fù)雜商業(yè)應(yīng)用則包含5或以上的層。
分層架構(gòu)模式的每層都有一個(gè)特定的 角色和責(zé)任,這叫分工,好區(qū)分責(zé)任,如果后續(xù)出錯(cuò)也好排查,大家都愛吃大鍋飯,因?yàn)椴粨?dān)責(zé)任,但慢慢地大鍋飯最后無法開鍋了。例如,一個(gè)展示層對于處理所有用戶交互和瀏覽器交互邏輯(然而一個(gè)業(yè)務(wù)層對于這行特定的關(guān)聯(lián)請求的特定業(yè)務(wù)有責(zé)任)。在架構(gòu)中的每層都圍繞需要做來滿足通常的業(yè)務(wù)請求的工作來建立一個(gè)抽象、例如展示層不必知道或擔(dān)心如何得到用戶數(shù)據(jù);它僅僅需要以常用的格式來在屏幕上呈現(xiàn)信息。類似地,業(yè)務(wù)層不必關(guān)心關(guān)于如何形成用戶數(shù)據(jù)來展示在屏幕上或甚至用戶數(shù)據(jù)從哪里來;它只需要從持久層得到數(shù)據(jù), 執(zhí)行業(yè)務(wù)邏輯與數(shù)據(jù)(例如,減值和合計(jì)數(shù)據(jù)),把這些信息向上傳遞給展示層。
分層架構(gòu)模式的一個(gè)強(qiáng)大的特性便是小組件之間的分離問題。在特定層內(nèi)的小組件僅僅處理對于那個(gè)層的特定邏輯,例如在展示層中的小組件僅僅處理展示邏輯,反之 組件駐留在業(yè)務(wù)層只處理業(yè)務(wù)邏輯。這種類型的組件分類便于模型到你的架構(gòu),建立有效的角色和責(zé)任,也便于開發(fā)、測試、管理和維護(hù)應(yīng)用程序使用這個(gè)架構(gòu)模式由于定義良好的組件接口和有限的組件范圍。
1.2 關(guān)鍵性概念
如圖所示
在架構(gòu)中的每一層都被標(biāo)記為關(guān)閉,這是一個(gè)非常重要的概念。一個(gè)關(guān)閉的層意味著作為一個(gè)請求從層到層,它必須經(jīng)過層下面去下一層的下面。例如請求來自表示層必須首先通過業(yè)務(wù)層和持久層,最后到達(dá)數(shù)據(jù)庫層。
為什么不允許表示層直接存取到要么持久層要么數(shù)據(jù)庫層呢?畢竟,直接數(shù)據(jù)庫從表示層存取比經(jīng)過不必要層的一串去檢索或保存數(shù)據(jù)庫信息更加快?這個(gè)問題的答案就在于分層的模式的關(guān)鍵概念-層隔離。
層隔離的概念意味著在架構(gòu)中的一層內(nèi)的變化通常不能影響或感染在其他層的組件。這個(gè)變化對于那個(gè)層內(nèi)的組件是被隔離的。可能另外的關(guān)聯(lián)層(例如一個(gè)包含SQL的持久層)。如果你運(yùn)行表示層直接存取到持久層,然后更改SQL在持久層會(huì)在業(yè)務(wù)層和表示層之間有影響,從而產(chǎn)生一個(gè)非常緊密耦合的應(yīng)用程序的組件之間的相互依賴關(guān)系,這種類型的架構(gòu)就變得非常困難并且敖貴。隔離層的概念也意味著每一個(gè)層是獨(dú)立于其它層,從而有很少或者沒有其他層內(nèi)部工作的知識(shí)架構(gòu)。考慮一個(gè)大型展示框架重構(gòu)工作從JSF JSF(如假設(shè)合同,模型)表示層和業(yè)務(wù)層之間使用保持不變,不影響業(yè)務(wù)層的重構(gòu)和保持完全獨(dú)立類型的用戶界面表示層所采用的框架。
雖然封閉層促進(jìn)層體系結(jié)構(gòu)內(nèi)的隔離,從而有助于隔離變化,有些時(shí)候?qū)τ谀承拥拈_放是有意義的。例如,假設(shè)您要添加一個(gè)共性服務(wù)層架構(gòu) 包含服務(wù)組件,訪問組件在業(yè)務(wù)層(如數(shù)據(jù)和字符串使用程序類或?qū)徲?jì)和日積類)。創(chuàng)建一個(gè)服務(wù)層通常是一個(gè)比較好的主意在這樣的情況下,因?yàn)榧軜?gòu)限制訪問共性服務(wù)業(yè)務(wù)層(而不是表示層)。沒有一個(gè)單獨(dú)的層,沒有什么架構(gòu)限制表示層訪問這些公共服務(wù),很難控制這個(gè)訪問限制。在這個(gè)示例中,新的業(yè)務(wù)服務(wù)層可能駐留在一層一層表明組件在這個(gè)服務(wù)不是從表示層訪問。業(yè)務(wù)層現(xiàn)在需要通過服務(wù)層持久層,這一點(diǎn)意義都沒有,分層架構(gòu)是一個(gè)古老的問題,解決了在架構(gòu)內(nèi)創(chuàng)建開放的層
如下面的插圖所示,這個(gè)事件中的服務(wù)層被標(biāo)記為開放,意味著請求被允許去繞開開放的層然后直接進(jìn)入它下面的層。在下面的例子中,自從服務(wù)層開放,業(yè)務(wù)層被允許繞開它然后直接進(jìn)入持久層,這完全講得通。

影響開放的概念和關(guān)閉的層幫助在架構(gòu)層和請求留之間定義了關(guān)系,并且在架構(gòu)中用必要的信息去理解變化層存取限制去提供給設(shè)計(jì)者和開發(fā)者。帶文件的失敗或者在架構(gòu)中強(qiáng)檔的交互式開放和關(guān)閉的通常緊密聯(lián)系,易碎的架構(gòu)是非常難與測試,維護(hù)和部署。
1.3 模式例子
舉例說明分層的架構(gòu)如何工作,考慮一個(gè)從業(yè)務(wù)層用戶到重新得到用戶信息、
例子中消費(fèi)者信息由2部分組成,消費(fèi)者數(shù)據(jù)和訂單數(shù)據(jù)
用戶屏幕對于接受請求并顯示用戶消息有責(zé)任,它不知道數(shù)據(jù)來自哪里,如何檢索,甚至多少數(shù)據(jù)庫被檢索來得到數(shù)據(jù)。一旦用戶屏幕接受了一個(gè)請求對于通常的個(gè)人去得到用戶消息,它然后轉(zhuǎn)發(fā)那個(gè)請求到用戶代理模型上。這個(gè)模型對于這點(diǎn)在業(yè)務(wù)層
處理那個(gè)請求的哪個(gè)模型是有責(zé)任的,并且然后到達(dá)那個(gè)模組,數(shù)據(jù)需要什么。消費(fèi)者對象在業(yè)務(wù)層對于合計(jì)通過業(yè)務(wù)請求需要的所有信息是有效的,這個(gè)模型召喚到用戶dao模型(在持久層內(nèi))去得到用戶數(shù)據(jù),并且order dao模型去得到訂單信息。這些模型在轉(zhuǎn)換執(zhí)行SQL語句去檢索正確響應(yīng)數(shù)據(jù)然后傳送它返回到客戶對象。一旦客戶對象重新得到數(shù)據(jù),它合計(jì)這些數(shù)據(jù)然后傳送這些信息到用戶代理門,然后傳送那個(gè)數(shù)據(jù)到用戶屏幕最后展示給了用戶查看。
2,分層的考慮
分層的結(jié)構(gòu)模式是一個(gè)堅(jiān)實(shí)的通用模式,使它有一個(gè)很好的起點(diǎn)對于大多數(shù)應(yīng)用程序,尤其是當(dāng)你不確定體系結(jié)構(gòu)模式是最適合您的應(yīng)用程序,然而當(dāng)選擇此模式時(shí),有幾個(gè)事情要從體系結(jié)構(gòu)的角度去考慮。
1,架構(gòu)抗反模式,此模式描述的情況通過多層體系勾結(jié)的簡單請求流直通處理很少或根本沒有邏輯執(zhí)行在每個(gè)層。例如,假設(shè)表示層響應(yīng)來自用戶的請求來檢索客戶數(shù)據(jù)。表示層將請求傳遞到業(yè)務(wù)層,它將請求傳遞到持久層,然后進(jìn)行簡單的SQL調(diào)用來檢索客戶數(shù)據(jù)到數(shù)據(jù)庫層,然后通過追溯數(shù)據(jù)堆棧沒有額外處理或邏輯聚合,計(jì)算或轉(zhuǎn)換數(shù)據(jù)。每一個(gè)分層結(jié)構(gòu)將至少有一些場景,落入抗反模式架構(gòu),然而,關(guān)鍵是分析調(diào)入這個(gè)類別的百分比。80-20規(guī)則通常是一個(gè)很好的實(shí)踐,遵循它來確定你是否在經(jīng)歷架構(gòu)抗反模式。電信的有大約20%的請求一樣簡單直通處理,80% 請求與請求相關(guān)的一些業(yè)務(wù)邏輯,然而如果你發(fā)現(xiàn)這個(gè)比例逆轉(zhuǎn),大部分簡單直通處理你的請求,你可能想要考慮的一些架構(gòu)層開放,這將是更難控制改變由于缺乏層隔離。分層架構(gòu)模式的另外一個(gè)考慮是,它往往借向獨(dú)立應(yīng)用程序本身,即使你把表示層和業(yè)務(wù)層分割成單獨(dú)的部署但愿,雖然這可能不是一個(gè)問題,對于某些應(yīng)用程序而言,它存在潛在問題的部署,可靠性,性能,可擴(kuò)展性
模式分析
全敏捷性:它是一種能力去快速響應(yīng)到一個(gè)持續(xù)改變的環(huán)境,當(dāng)改變能通過隔離層特性被隔離,它仍然是累贅的并且耗時(shí)的在這個(gè)架構(gòu)內(nèi)做改變因?yàn)榇蠖鄶?shù)實(shí)現(xiàn)的整體性以及緊密耦合的組件以這樣的模式通常被發(fā)現(xiàn),因此它的全敏捷性低。
易部署:基于你要如何實(shí)現(xiàn)這個(gè)模式,部署會(huì)成為一個(gè)問題,這主要是針對更大的應(yīng)用程序。一個(gè)到一個(gè)組件的小的變化能要求一個(gè)全部應(yīng)用的一個(gè)再部署。結(jié)果在于部署需要被計(jì)劃,被安排,被執(zhí)行(在非高峰時(shí)間或是周末),基于此,這個(gè)模式不容易借向持續(xù)交付管道本身,進(jìn)一步減少總評(píng)部署。因此部署性低。
可擴(kuò)展性:由于緊密耦合的趨勢和整體的實(shí)現(xiàn),應(yīng)用程序構(gòu)建使用這個(gè)模式通常很難,你可以擴(kuò)展一個(gè)分層架構(gòu)層分割到不同的物理部署或整個(gè)應(yīng)用程序賦值到多個(gè)節(jié)點(diǎn),但總體粒度太廣泛因而使得其代價(jià)昂貴,因?yàn)榭蓴U(kuò)展性低。
可開發(fā)性:易于開發(fā)得到相對高的分?jǐn)?shù),主要是因?yàn)檫@種模式是如此出名,不過過于復(fù)雜的實(shí)現(xiàn)。因?yàn)榇蠖鄶?shù)公司通過分離技能開發(fā)應(yīng)用程序?qū)樱@個(gè)模式就變成了一個(gè)自然的選擇。公司之間的聯(lián)系溝通和組織機(jī)構(gòu)和軟件開發(fā)方式概述了什么是被稱為康威定律,關(guān)于這個(gè)迷人的相關(guān)性你可以谷歌conway法則來獲取更多的信息。
可測試性:因?yàn)榻M件屬于特定的層,其他層能被失效或被存根,使得這個(gè)模式相對容易測試。
性能:當(dāng)它是真的一些層架構(gòu)師性能可以,這個(gè)模式不借向高性能應(yīng)用歸于必須經(jīng)歷結(jié)構(gòu)的多層去實(shí)現(xiàn)一個(gè)業(yè)務(wù)請求,因此性能低。