2.軟件架構(gòu)預(yù)述(譯)

原文:https://herbertograca.com/2017/07/05/software-architecture-premises/

這篇文章是軟件架構(gòu)編年史()的一部分,這部編年史由一系列關(guān)于軟件架構(gòu)的文章組成。在這一系列文章中,我將寫下我對軟件架構(gòu)的學(xué)習(xí)和思考,以及我是如何運用這些知識的。如果你閱讀了這個系列中之前的文章,本篇文章的的內(nèi)容將更有意義。
在這篇文章中,我將總結(jié)一些關(guān)于軟件架構(gòu)的最基本的概念,了解它們才能更好地理解后續(xù)的文章。

沒有銀彈

無論你如何理解我在軟件架構(gòu)編年史()中談到的內(nèi)容,首先要理解的是沒有銀彈,沒有“普適性”的解決方案。盡可能地了解不同的方法,理解每一種方法的優(yōu)劣,和它們解決的特定技術(shù)問題。

然后,當(dāng)接受新的挑戰(zhàn)時,先從理解業(yè)務(wù)和最終用戶的需求開始。在搞清楚這些需求之后,你才能思考應(yīng)該采用哪些架構(gòu)風(fēng)格和模式來更好地解決這些問題。

最后,自己做出選擇,是實現(xiàn)一種已知的解決方案,還是創(chuàng)造適合自己的特定問題的獨特設(shè)計。

有些架構(gòu)風(fēng)格號稱是所有形式的軟件的“銀彈”。然而,優(yōu)秀的設(shè)計這應(yīng)該選擇最符合解決特定問題需要的風(fēng)格?!猂oy Fielding, 2000 [1]

術(shù)語

在軟件開發(fā)的世界中使用的術(shù)語很多都模棱兩可,因此,我必須澄清一些我使用的術(shù)語的含義,然后繼續(xù)。

功能性(Functional)

在應(yīng)用中純粹發(fā)揮技術(shù)作用的代碼片段、方法、類、類的組合。它們和(業(yè)務(wù))領(lǐng)域無關(guān)僅僅代表應(yīng)用中的一種技術(shù)能力。例如:

  • 層次(Layer)
  • 工廠(Factory)
  • 資源庫(Repository)
  • 值對象(Value Object)
  • 視圖(View)
  • 視圖模型(ViewModel)

概念性(Conceptual)

在應(yīng)用中標(biāo)識一個(業(yè)務(wù))領(lǐng)域概念的代碼片段、方法、類、類的組合。它們和領(lǐng)域相關(guān),代表應(yīng)用中的一種業(yè)務(wù)能力。例如:

  • 用戶
  • 產(chǎn)品
  • 庫存管理
  • 產(chǎn)品變體
  • 結(jié)帳
  • 銷售

這種劃分并不是說一個代碼單元不能同時具備兩種能力(功能性和概念性)。例如,“Money”對象可以表示一個領(lǐng)域概念,同時也被設(shè)計成一個值對象。如果我把它當(dāng)成領(lǐng)域概念,我指的就是領(lǐng)域內(nèi)的金錢概念,但如果我涉及的是這個類中的功能性方面時,我指的就是值對象的技術(shù)特性(沒有ID、可以是不變的等等)。

包(Package)

劃分在一起的類組成的集合,理想情況下遵循一組規(guī)則進(jìn)行劃分。

模塊(Module)

我使用Software Architecture in Practice[7]給出的定義,模塊就是一個功能性包,它體現(xiàn)了應(yīng)用中的一種技術(shù)能力。它是解耦的并且能夠被其他的實現(xiàn)替換。我的理解是,模塊即存在與較低的粒度級別,比如,“安全模塊”或者“ORM”,也可以存在于像客戶端服務(wù)器這樣的應(yīng)用塊。模塊提供的是功能性內(nèi)聚。

組件(Component)

我使用Software Architecture in Practice[7]給出的定義,作者將組件定義為一個代表業(yè)務(wù)能力概念性包。理想情況下,它也是和其他組件和模塊解耦的。例如“用戶”、“產(chǎn)品”或“結(jié)帳”。

然而,最重要的是要記住,理想情況下,它代表了一個限界上下文(Bounded Context)。組件提供了概念性內(nèi)聚。

應(yīng)用(Application)

我將面向用戶的代碼即 UI 視為應(yīng)用,它建立在組件之上。例如,我們可以基于一組組件構(gòu)建網(wǎng)絡(luò)商店。不管怎樣,這個網(wǎng)絡(luò)商店會提供一個(店面) UI 讓用戶瀏覽和購買商品和另一個(管理) UI 讓商店管理員管理商品、庫存、支付供應(yīng)商,等等。這是在同樣的業(yè)務(wù)組件之上構(gòu)建的兩個獨立的應(yīng)用。

系統(tǒng)(System)

我認(rèn)為系統(tǒng)是一組以某種方式在一起工作,為各種企業(yè)必需品提供功能,形成一個企業(yè)范圍內(nèi)的系統(tǒng),即企業(yè)應(yīng)用。這些應(yīng)用可能構(gòu)建在相同或不同的組件上。在之前網(wǎng)絡(luò)商店的例子中,系統(tǒng)就是作為一個整體的網(wǎng)絡(luò)商店,包括兩個基于同樣業(yè)務(wù)組件構(gòu)建的兩個應(yīng)用(店面和管理),還有其他像支付供應(yīng)商或貨運供應(yīng)商這樣的第三方應(yīng)用。

架構(gòu)(Architecture)

軟件架構(gòu)的簡單定義有很多,我覺得都不錯,但我認(rèn)為理解它是什么很簡單,而更重要的是,定義架構(gòu)的產(chǎn)出,它應(yīng)該給項目帶來什么。

軟件架構(gòu)[…]是系統(tǒng)需要考慮的一組結(jié)構(gòu),它們包括軟件元素和它們之間的關(guān)系,以及這些元素和關(guān)系的屬性?!?Clements et al, 2010 [6]

下面是我考慮架構(gòu)的方面:

  • 橫跨所有特性開發(fā)的技術(shù)決策,例如,框架、代碼標(biāo)準(zhǔn)、文檔、流程,...;
  • 這是存在于項目中的一組很難在后期改變的技術(shù)決策 [3]
  • 它是系統(tǒng)的全景圖[5]:pp.2,粗略的描繪,結(jié)構(gòu),組件及其關(guān)系[4] [6];
  • 它使項目做好變化的準(zhǔn)備[5]:pp.30,常常是將決策推遲到最后允許的時刻[5]:pp.32;
  • 它讓項目做好重用組件和模塊的準(zhǔn)備[7]:pp.29–35;
  • 它制定出結(jié)果的一致性標(biāo)準(zhǔn)并建立輕量的流程,比如編碼規(guī)范、開發(fā)階段、持續(xù)交付和持續(xù)部署;
  • 不是某一個人的職責(zé),而是由來自項目中不同特性團(tuán)隊的開發(fā)者組成的行會的職責(zé)。

如果你不熟悉行會的概念,可以觀看下面關(guān)于Spotify 工程師文化的視頻:

架構(gòu)師(Architect)

他是由行會討論和決定的架構(gòu)的發(fā)起人和守護(hù)者。他是部門/團(tuán)隊中經(jīng)驗最豐富的開發(fā)者之一,恰好承擔(dān)著分析高層次問題和解決方案的額外職責(zé)。在做出架構(gòu)決策時,他還擁有“質(zhì)量票”(He also benefits from a “quality vote” when making an architectural decision.)。

可是,有一點值得注意,所有開發(fā)者某種程度上都是架構(gòu)師,因為他們都要了解架構(gòu),他們都會議某種形式參與架構(gòu),他們都適當(dāng)?shù)爻袚?dān)著維護(hù)架構(gòu)的職責(zé)。

象牙塔架構(gòu)師(Ivory Tower Architect)

有一種架構(gòu)師會做出和架構(gòu)有關(guān)的所有決定,這種萬能的象牙塔架構(gòu)師是一種架構(gòu)師的反模式。他對其他干系人對架構(gòu)的貢獻(xiàn)既不開放,也不輕易接收,而是閹割了這些貢獻(xiàn)。

Smells of a bad Architecture (and bad code) [8]

僵化(Rigidity)

如果軟件難以修改是因為修改會導(dǎo)致更多關(guān)聯(lián)修改,軟件就是僵化的。它就會變成兔子洞:當(dāng)我們以為修改快要完成時,突然發(fā)現(xiàn)還有更多的代碼需要修改,把我們拉進(jìn)無止盡的輪回之中。

脆弱(Fragility)

脆弱的軟件在修改時,總會出現(xiàn)意料之外的、毫無關(guān)聯(lián)的、無法預(yù)測的錯誤。

牢固(Immobility)

如果設(shè)計包含一些可以在其它系統(tǒng)中使用的部分,但將這些部分從原系統(tǒng)中分離出來需要大量工作甚至帶來許多風(fēng)險,我們就說設(shè)計是牢固的。

粘滯(Viscosity)

在一個粘滯的系統(tǒng)中,要做對困難重重,要做錯卻輕而易舉。這意味著通過正常開發(fā)實現(xiàn)變更不如用非常手段來得容易。

如果執(zhí)行單元測試和/或編譯需要耗費很長時間,開發(fā)很可能導(dǎo)跳過這些過程,不跑任何自動化測試就實現(xiàn)非常規(guī)的修改,這就是系統(tǒng)范圍的粘滯。

不必要的重復(fù)(Needless repetition)

當(dāng)時間不夠或經(jīng)驗不足導(dǎo)致必要的抽象缺失時,就會產(chǎn)生不必要的重復(fù)。這些代碼也許并不是直接復(fù)制粘貼造成的重復(fù),而是由在不同地方重復(fù)定義的相同業(yè)務(wù)規(guī)則帶來的。

晦澀(Opacity)

代碼寫得混亂,難以理解,我們需要深人方法實現(xiàn)的細(xì)節(jié)才能搞清楚代碼要干什么。

不必要的復(fù)雜(Needless complexity)

開發(fā)者采用了多種不同的抽象和未來潛在變化的應(yīng)對措施,來積極地避免其他六種壞味道。良好的軟件設(shè)計是輕量靈活的,理解起來更容易,最重要的是修改更容易,因此不必預(yù)判所有未來的潛在變化。

引用來源

[1] 2000 – Roy Fielding – Architectural Styles and the Design of Network-based Software Architectures
[2] 2000 – Robert C. Martin – Design Principles and Design Patterns
[3] 2006 – Booch, in [5 pg.2]
[4] 2007 – IEEE1471 in [5 pg.2]
[5] 2010 – James Coplien, Gertrud Bjornvig – Lean Architecture
[6] 2010 – Paul Clements, Felix Bachmann, Len Bass – Documenting Software Architectures
[7] 2012 – Len Bass, Paul Clements, Rick Kazman – Software Architecture in Practice
[8] 2014 – M. H. Jongerius – THE SEVEN DESIGN SMELLS OF ROTTING SOFTWARE
[9] 2017* – Wikipedia – Software Architecture

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 結(jié)婚至今整整十個年頭了,每年的春節(jié)似乎都是先生在哪里我們便在哪個城市過年。于是便有很多異鄉(xiāng)的年。 記憶里仍然有軍營...
    深香默默閱讀 298評論 2 0
  • 2017年5月16日 晴 雷靜 欣賞自己:任何時候都不能做井底之蛙,可能在我們自己的眼光里總是覺得還不...
    FAB夏染閱讀 324評論 0 0
  • 分享78天(和女兒熬夜追?。┲芏?.28 被大家議論引起好奇,說《延禧攻略》好看,我周六忙完工作,終于可以 休息,...
    蕾小姐愛學(xué)習(xí)閱讀 339評論 0 0
  • 一 小學(xué)的時候,世界很小很天真,門前的流水,天上的白云,日出抑或黃昏,靜靜陪伴成長。沒有汽車的鳴笛,沒...
    不對自己說謊閱讀 461評論 0 0
  • 早上醒來,打開窗戶,四周一片白茫茫的,這場雪說大不大,但卻也遮住了茫茫天地。學(xué)校四周的房子,宿舍樓前的小花園,操場...
    明陽小妹閱讀 496評論 0 2

友情鏈接更多精彩內(nèi)容