《架構(gòu)整潔之道》摘記

第1部分:概述

  • 軟件架構(gòu)的終極目標時,用最小的人力成本來滿足構(gòu)建和維護該系統(tǒng)的需求

  • 本書的主題:描述什么是優(yōu)秀的、整潔的軟件架構(gòu)與設(shè)計

  • 兩個價值維度

  • 行為價值:讓機器按照某種指定方式運轉(zhuǎn)

  • 架構(gòu)價值:軟件系統(tǒng)的靈活性,即是否容易被修改

  • 如果忽略軟件架構(gòu)的價值,系統(tǒng)將會變得越來越難以維護,終會有一天,系統(tǒng)將會變得再也無法修改。

第2部分:從基礎(chǔ)構(gòu)建開始:編程范式

結(jié)構(gòu)化編程

  • 結(jié)構(gòu)化編程對程序控制權(quán)的直接轉(zhuǎn)移進行了限制和規(guī)范
  • 用順序結(jié)構(gòu)、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)可構(gòu)造出任何程序
  • 結(jié)構(gòu)化編程范式可將模塊遞歸拆分為可推導(dǎo)的單元
  • goto有害,某些用法會導(dǎo)致某個模塊無法被遞歸拆分成更小、可證明的單元

面向?qū)ο缶幊?/h4>
  • 面向?qū)ο缶幊虒?strong>程序控制權(quán)的間接轉(zhuǎn)移進行了限制和規(guī)范
  • 面向?qū)ο缶幊叹褪且远鄳B(tài)為手段來對源代碼中的依賴關(guān)系進行控制的能力,這種能力讓軟件架構(gòu)師可以構(gòu)建出某種插件式架構(gòu),讓高層策略性組件與底層實現(xiàn)性組件相分離,底層組件可以被編譯成插件,實現(xiàn)獨立于高層組件的開發(fā)和部署

函數(shù)式編程

  • 函數(shù)式編程對程序中的賦值進行了限制和規(guī)范

  • 可變變量導(dǎo)致競爭問題、死鎖問題、并發(fā)更新問題

  • 不可變性方案:

  • 一個架構(gòu)設(shè)計良好的應(yīng)用程序應(yīng)該將狀態(tài)修改的部分和不需要修改狀態(tài)的部分隔離成單獨的組件,然后用合適的機制來保護可變量。軟件架構(gòu)師應(yīng)該致力于將大部分處理邏輯都歸于不可變組件中,可變狀態(tài)組件的邏輯應(yīng)該越少越好。

  • 事件溯源:只存儲事務(wù)記錄,不存儲具體狀態(tài)。當需要具體狀態(tài)時,從頭開始計算所有的事務(wù)。當只有CR,沒有UD,自然也就不存在并發(fā)問題。

第3部分:設(shè)計原則

SRP:單一職責原則

  • Single Responsibility Principle
  • There should never be more than one reason for a class to change
  • 單一職責原則主要討論的是函數(shù)和類之間的關(guān)系--但是它在兩個討論層面上會以不同的形式出現(xiàn)。在組件層面,我們可以將其稱為共同必包原則(Common Closure Principle),在軟件架構(gòu)層面,它則是用于奠定架構(gòu)邊界的變更軸心(Axis of Change)。

OCP:開閉原則

  • Open-Closed Principle
  • 設(shè)計良好的計算機軟件應(yīng)該易于擴展,同時抗拒修改
  • 其主要目標是讓系統(tǒng)易于擴展,同時限制器每次被修改所影響的范圍。實現(xiàn)方式是通過將系統(tǒng)劃分為一系列組件,并且將這些組件間的依賴關(guān)系按層次結(jié)構(gòu)進行組織,使得高階組件不會因低階組件被修改而受到影響。

LSP:里氏替換原則

  • Liskov Substitution Principle
  • 對于每個類型是S的對象o1,都存在一個類型為T的對象o2,能使操作T類型的程序P在用o2替換o1時行為保持不變,我們就可以將S稱為T的子類型。
  • 正方形/長方形問題:正方形不是長方形的子類,它們具有不同的修改邊長的邏輯

ISP:接口隔離原則

  • Interface Segregation Principle
  • 避免不必要的依賴
  • image.png

DIP:依賴反轉(zhuǎn)原則

  • Dependency Inversion Principle

  • 具體的編碼守則

  • 應(yīng)在代碼中多使用抽象接口,盡量避免使用那些多變的具體實現(xiàn)類

  • 不要在具體實現(xiàn)類上創(chuàng)建衍生類

  • 不要覆蓋包含具體實現(xiàn)的函數(shù)

  • 應(yīng)避免在代碼中寫入與任何具體實現(xiàn)相關(guān)的名字,或者是其他容易變動的事物的名字

  • 對易變對象的創(chuàng)建過程做一些處理,通常會選擇用抽象工廠模式來解決源代碼的依賴問題

  • 依賴方向與控制流方向相反

第4部分:組件構(gòu)建原則

組件

  • 組件是軟件的部署單元,是整個軟件系統(tǒng)在部署過程中可以獨立完成部署的最小實體。例如,對于Java來說,它的組件是jar文件。

組件聚合

  • 哪些類應(yīng)該被組合成一個組件呢?三個與構(gòu)建組件相關(guān)的基本原則:

  • REP:復(fù)用/發(fā)布等同原則(為復(fù)用性而組合)

  • 軟件復(fù)用的最小粒度應(yīng)等同于其發(fā)布的最小粒度

  • 組件中的類和模塊必須是彼此緊密相關(guān)的

  • CCP:共同閉包原則(為維護性而組合)

  • 我們應(yīng)該將那些會同時修改,并且為相同目的而修改的類放到同一個組件中,而將不會同時修改,并且不會為了相同目的而修改的那些類放到不同的組件中。

  • SRP原則在組件層面上的再度闡述,可共同概括為:將由于相同原因而修改,并且需要同時修改的東西放在一起;將由于不同原因而修改,并且不同時修改的東西分開。

  • CRP:共同復(fù)用原則(為避免不必要的發(fā)布而切分)

  • 不要強迫一個組件的用戶依賴他們不需要的東西

  • 和ISP可共同概括為:不要依賴不需要用到的東西

  • 組件聚合張力圖

1659167256317-99501afa-1a04-4447-bda5-32574645287a.png
  • REP和CCP是黏合性原則, 它們會讓組件變得更大,而CRP原則是排除性原則, 它會盡量讓組件變小。
  • 一般來說,一個軟件項目的重心會從該三角區(qū)域的右側(cè)開始,先期主要犧牲的是復(fù)用性。然后,隨著項目逐漸成熟,其他項目會逐漸開始對其產(chǎn)生依賴,項目重心就會逐漸向該三角區(qū)域的左側(cè)滑動。換句話說,一個項目在組件結(jié)構(gòu)設(shè)計上的重心是根據(jù)該項目的開發(fā)時間和成熟度不斷變動的,我們對組件結(jié)構(gòu)的安排主要與項目開發(fā)的進度和它被使用的方式有關(guān),與項目本身功能的關(guān)系其實很小。

組件耦合

  • 三條主要關(guān)注組件之間關(guān)系的原則:

  • ADP:無依賴環(huán)原則

  • 組件依賴關(guān)系圖中不應(yīng)該出現(xiàn)環(huán)

  • 循環(huán)依賴會使得組件的獨立維護、單元測試和發(fā)布流程變得困難

  • 打破依賴循環(huán)的兩種方式:

  • 應(yīng)用依賴反轉(zhuǎn)原則(DIP),依賴于接口而不是實現(xiàn)

  • 創(chuàng)建一個新的組件,將現(xiàn)有組件互相依賴的類全部放入新組件

  • SDP:穩(wěn)定依賴原則

  • 依賴關(guān)系必須要指向更穩(wěn)定的方向

  • 任何一個我們預(yù)期會經(jīng)常變更的組件都不應(yīng)該被一個難于修改的組件所依賴,否則這個多變的組件也將會變得非常難以修改。(通過遵守穩(wěn)定依賴原則解決)

  • 當組件不依賴于任何組件,則不會有任何原因?qū)е滤枰蛔兏?,我們稱它為“獨立”組件

  • 一種計算組件穩(wěn)定性的方式,I指標:I = Fan-out / (Fan-in + Fan-out)

  • Fan-in: 入向依賴,組件外部類依賴于組件內(nèi)部類的數(shù)量

  • Fan-out: 出向依賴,組件內(nèi)部類依賴于組件外部類的數(shù)量

  • I 不穩(wěn)定性,指標范圍是[0, 1],值越小越穩(wěn)定

  • 每個組件的I指標都必須大于其所依賴組件的I指標,即組件結(jié)構(gòu)依賴圖中的I指標必須要按其依賴關(guān)系方向遞減。

  • 可使用DIP來解決違反穩(wěn)定依賴原則的組件依賴

  • SAP:穩(wěn)定抽象原則

  • 一個組件的抽象化程度應(yīng)該與其穩(wěn)定性保持一致

  • 該原則要求穩(wěn)定的組件同時應(yīng)該是抽象的,這樣它的穩(wěn)定性就不會影響到擴展性;另一方面,該原則也要求一個不穩(wěn)定的組件應(yīng)該包含具體的實現(xiàn)代碼,這樣它的不穩(wěn)定性就可以通過具體的代碼被輕易修改。

  • 對組件抽象化程度的一個衡量方式,A指標:A = Na / Nc

  • Nc: 組件中類的數(shù)量

  • Na: 組件中抽象類和接口的數(shù)量

  • A:抽象程度

  • 穩(wěn)定程度與抽象化程度的區(qū)間分析

1659187162660-87dba48a-2cea-43f3-bd60-607b1f1b2860.png
  • 痛苦區(qū):非常穩(wěn)定但也非常具體,難以被修改
  • 無用區(qū):抽象但沒有被其他組件依賴
  • 最優(yōu)的位置是主序列線的兩端,實際項目中貼近線即可
  • 衡量一個組件距離最佳位置的指標,D指標:D=|A+I-1|

第5部分:軟件架構(gòu)

什么是軟件架構(gòu)

  • 軟件架構(gòu)這項工作的實質(zhì)就是規(guī)劃如何將系統(tǒng)切分成組件,并安排好組件之間的排列關(guān)系,以及組件之間互相通信的方式。
  • 設(shè)計軟件架構(gòu)的目的是為了在工作中更好地對這些組件進行研發(fā)、部署運行以及運維;最大化程序員的生產(chǎn)力,同時最小化系統(tǒng)的總運營成本。
  • 將軟件的高層策略與其底層實現(xiàn)隔離開
  • 一個優(yōu)秀的軟件架構(gòu)師應(yīng)該致力于最大化可選項數(shù)量

獨立性

  • 康威定律:任何一個組織在設(shè)計系統(tǒng)時,往往都會復(fù)制出一個與該組織內(nèi)部溝通結(jié)構(gòu)相同的系統(tǒng)。

  • 將系統(tǒng)正確地劃分為一些隔離良好的組件,以便盡可能長時間地為我們的未來保留盡可能多的可選項

  • 通過采用單一職責原則(SRP)和共同閉包原則(CCP),以及既定的系統(tǒng)設(shè)計意圖來隔離那些變更原因不同的部分,集成變更原因原因相同的部分

  • 按層解耦:UI界面、應(yīng)用獨有的業(yè)務(wù)邏輯、領(lǐng)域普適的業(yè)務(wù)邏輯、數(shù)據(jù)庫等。

  • 用例的解耦:根據(jù)用例進行垂直切片(比如添加訂單和刪除訂單)

  • 解耦模式

  • 源碼層次:源代碼模塊之間的依賴;系統(tǒng)所有的組件都會在同一個地址空間內(nèi)執(zhí)行,通過簡單的函數(shù)調(diào)用來進行彼此的交互;通常叫做單體結(jié)構(gòu)。

  • 部署層次:部署單元(譬如jar文件、DLL、共享庫等)之間的依賴;大部分組件可能還是依然運行在同一個地址空間內(nèi),通過彼此的函數(shù)調(diào)用通信,部分嗎可能會運行在同一個處理器下的其他進程內(nèi);可以產(chǎn)生出許多可獨立部署的單元。

  • 服務(wù)層次:通過網(wǎng)絡(luò)數(shù)據(jù)包進行通信;每個執(zhí)行單元在源碼層和二進制層都會是一個獨立的個體。

  • 一個設(shè)計良好的架構(gòu)應(yīng)該允許一個系統(tǒng)從單體結(jié)構(gòu)開始,以單一文件的形式部署,然后逐漸成長為一組相互同理的可部署單元,甚至是獨立的服務(wù)或者微服務(wù)。最后還能隨著情況的變化,允許系統(tǒng)逐漸回退到單體結(jié)構(gòu)。

劃分邊界

  • 邊界的作用是將軟件分割成各種元素,以便約束邊界兩側(cè)之間的依賴關(guān)系
  • 盡可能地推遲細節(jié)性的決策(采用的框架、數(shù)據(jù)庫、web服務(wù)器、工具庫、依賴注入等),并將這種推遲所產(chǎn)生的影響降低到最低
  • 過早的細節(jié)性決策會浪費大量人力
  • 邊界線應(yīng)該畫在那些不相關(guān)的事情中間,比如GUI、業(yè)務(wù)邏輯、數(shù)據(jù)庫
1659366285458-7c4b6bb2-8459-467c-8a6d-ce6f94b4bd67.png
  • 數(shù)據(jù)庫可以采用多種實現(xiàn),而業(yè)務(wù)邏輯并不需要關(guān)心這件事。這意味著我們可以將與數(shù)據(jù)庫相關(guān)的決策延后,先專注編寫業(yè)務(wù)邏輯的代碼,進行測試,直到不得不選擇數(shù)據(jù)庫為止。
  • 插件式架構(gòu)
  • 為了在軟件架構(gòu)中畫邊界線,我們需要先將系統(tǒng)分割成組件,其中一部分是系統(tǒng)的核心業(yè)務(wù)邏輯組件,而另一部分則是與核心業(yè)務(wù)邏輯無關(guān)但負責提供必要功能的插件。然后通過對源代碼的修改,讓這些非核心組件依賴于系統(tǒng)的核心業(yè)務(wù)邏輯組件。這也是一種對依賴反轉(zhuǎn)原則(DIP)和穩(wěn)定抽象原則(SAP)的具體應(yīng)用,依賴箭頭應(yīng)該由底層具體實現(xiàn)細節(jié)指向高層抽象的方向。

邊界剖析

  • 邊界形式

  • 單體結(jié)構(gòu):低層客戶端調(diào)用高層服務(wù)函數(shù)

  • 部署層次的組件:動態(tài)鏈接庫

  • 線程?

  • 本地進程

  • 服務(wù)

策略和層次

  • 策略:描述計算部分的業(yè)務(wù)邏輯、描述計算報告的格式、描述如何校驗輸入數(shù)據(jù)等
  • 層次:一條策略具體系統(tǒng)的輸入/輸出越遠,它所屬的層次就越高
  • 在一個設(shè)計良好的架構(gòu)中,依賴關(guān)系的方向通常取決于它們所關(guān)聯(lián)的組件層次。一般來說,低層組件被設(shè)計為依賴于高層組件。
錯誤:
function encrypt() {
  while(true)
    writeChar(translate(readChar()))
}
高層組件encrypt()依賴于低層組件中的函數(shù)readChar()和writeChar()

正確:
Encrypt類依賴于Char Reader接口和Char Writer接口,由具體類實現(xiàn)接口方法。這樣低層組件(實現(xiàn)類)就變成依賴于高層組件(Encrypt類加兩個接口)

業(yè)務(wù)邏輯

  • 關(guān)鍵業(yè)務(wù)邏輯和關(guān)鍵業(yè)務(wù)數(shù)據(jù)是緊密相關(guān)的,所以它們很適合被放在同一個對象中處理,這種對象也被叫做“業(yè)務(wù)實體(Entity)”
  • 業(yè)務(wù)實體獨自代表了整個業(yè)務(wù)邏輯,它與數(shù)據(jù)庫、用戶界面、第三方框架等內(nèi)容無關(guān)
  • 用例更靠近系統(tǒng)的輸入和輸出,屬于低層概念;而業(yè)務(wù)實體是一個可以適用于多個應(yīng)用情景的一般化概念,相對地離系統(tǒng)的輸入和輸出更遠。所以用例依賴于業(yè)務(wù)實體,而業(yè)務(wù)實體并不依賴于用例。
  • 不要選擇直接在數(shù)據(jù)結(jié)構(gòu)中使用對業(yè)務(wù)實體對象的引用!這兩個對象存在的意義是非常不一樣的,而且這兩個對象會以不同的原因、不同的速率發(fā)生變更。整合在一起是對共同閉包原則(CCP)和單一職責原則(SRP)的違反。

尖叫的軟件架構(gòu)

  • 軟件的系統(tǒng)架構(gòu)應(yīng)該為該系統(tǒng)的用例提供支持。 -- 《Object Oriented Software Engineering, A Use Case Driven Approach》
  • 一個良好的架構(gòu)設(shè)計應(yīng)該圍繞著用例來展開,這樣的架構(gòu)設(shè)計可以在脫離框架、工具以及使用環(huán)境的情況下完整地描述用例。
  • 避免讓框架主導(dǎo)我們的架構(gòu)設(shè)計
  • 在不依賴任何框架的情況下針對用例進行單元測試。另外,我們運行測試的時候不應(yīng)該運行web服務(wù),也不應(yīng)該需要連接數(shù)據(jù)庫。

整潔架構(gòu)

  • 各類架構(gòu)(六邊形架構(gòu)、DCI架構(gòu)、BCE架構(gòu)等)都具有同一個設(shè)計目標:按照不同關(guān)注點對軟件進行切割。也就是說,這些架構(gòu)都會將軟件切割成不同的層,至少有一層是只包含該軟件的業(yè)務(wù)邏輯的,而用戶接口、系統(tǒng)接口則屬于其他層。

  • 按照這些架構(gòu)設(shè)計出來的系統(tǒng),通常都具有以下特點:

  • 獨立于框架

  • 可被測試

  • 獨立于UI

  • 獨立于數(shù)據(jù)集

  • 獨立于任何外部機構(gòu)

  • 將上述所有架構(gòu)的設(shè)計理念綜合稱為一個獨立的理念:

image.png
  • 依賴關(guān)系規(guī)則

  • 通常越靠近中心,其所在的軟件層次就越高。基本上,外層圓代表的是機制,內(nèi)層圓代表的是策略。

  • 貫穿整個架構(gòu)設(shè)計的規(guī)則:源碼中的依賴關(guān)系必須只指向同心圓的內(nèi)層,即由低層機制指向高層策略。

  • 業(yè)務(wù)實體:封裝了該應(yīng)用中最通用、最高層的業(yè)務(wù)邏輯,它們應(yīng)該屬于系統(tǒng)中最不容易受外界影響而變動的部分。

  • 用例:通常包含的是特定應(yīng)用場景下的業(yè)務(wù)邏輯,這里面封裝并實現(xiàn)了整個系統(tǒng)的所有用例。這些用例引導(dǎo)了數(shù)據(jù)在業(yè)務(wù)實體之間的流入/流出,并指揮著業(yè)務(wù)實體利用其中的關(guān)鍵業(yè)務(wù)邏輯來實現(xiàn)用例的設(shè)計目標。

  • 接口適配器

  • 通常是一組數(shù)據(jù)轉(zhuǎn)換器,它們負責將數(shù)據(jù)從對用例和業(yè)務(wù)實體而言最方便操作的格式,轉(zhuǎn)換為外部系統(tǒng)(譬如數(shù)據(jù)庫以及web)和持久層框架最方便操作的格式。

  • 如果采用的是SQL數(shù)據(jù)庫,那么所有的SQL語句都應(yīng)該被限制在這一層的代碼中。

  • 這層也會負責將來自外部服務(wù)的數(shù)據(jù)轉(zhuǎn)換成系統(tǒng)內(nèi)用例和業(yè)務(wù)實體所需的格式

  • 框架和驅(qū)動程序:最外層的模型層一般是由工具、數(shù)據(jù)庫、web框架等組成。在這一層中,我們通常只需要編寫一些于內(nèi)層溝通的黏合性代碼。

  • 真正的架構(gòu)可能會超過四層,但是源碼層面的依賴關(guān)系一定要指向同心圓的內(nèi)層。

  • 通常采用依賴反轉(zhuǎn)原則(DIP)來解決控制流和依賴方向的相反性。

展示器和謙卑對象

  • 謙卑對象模式:將容易測試的行為和難以測試的行為拆分成兩組模塊或類,并將它們隔離。包含難以測試的行為的模塊被稱為謙卑(Humble)組。 (具體可參考 xUnit Test Patterns: Refractoring Test Code)
  • 謙卑組的代碼通常應(yīng)該越簡單越好
  • 強大的可測試性是一個架構(gòu)設(shè)計是否優(yōu)秀的顯著衡量標準之一
  • 因為跨邊界通信肯定需要用到某種簡單的數(shù)據(jù)結(jié)構(gòu),而邊界會自然而然地將系統(tǒng)分割成難以測試的部分與容易測試的部分,所以通過在系統(tǒng)的邊界處運用對象模式,我們可以大幅地提高整個系統(tǒng)的可測試性。

不完全邊界

  • 為了解決YAGNI原則(You aren't going to need it, 不要預(yù)測未來的需要)和架構(gòu)師工作本身(預(yù)見性設(shè)計)之間的矛盾,需要引入不完全邊界的概念。

  • 幾種不完全邊界策略,除此外還有許多其他實現(xiàn)方式,根據(jù)不同的場景進行選擇

  • 方式一:將系統(tǒng)分割成一系列可以獨立編譯、獨立部署的組件之后,再把它們構(gòu)建成一個組件。這樣可以省去多組件管理這部分的工作,比如版本號管理和發(fā)布管理等等。

  • 方式二:單向邊界。單側(cè)組件提供接口進行隔離,而不是采用雙向反向接口。

  • 方式三:門戶模式

  • 架構(gòu)師的職責之一就是預(yù)判未來哪里有可能需要設(shè)置架構(gòu)邊界,并決定應(yīng)該以完全形式還是不完全形式來實現(xiàn)它們。

層次與邊界

  • 架構(gòu)邊界可以存在于任何地方,必須要小心審視究竟在什么地方才需要設(shè)計架構(gòu)邊界。另外,必須弄清楚完全實現(xiàn)這些邊界將會帶來多大的成本。
  • 權(quán)衡利弊,反復(fù)進行

Main組件

  • Main組件是整個系統(tǒng)中的一個低層模塊,它處于整潔架構(gòu)的最外圈,主要負責為系統(tǒng)加載所有必要的信息,然后再將控制權(quán)轉(zhuǎn)交回系統(tǒng)的高層組件。

服務(wù):宏觀與微觀

  • 面向服務(wù)的“架構(gòu)”以及微服務(wù)“架構(gòu)”本身只是一種比函數(shù)調(diào)用方式成本稍高,分割應(yīng)用程序行為的一種形式,與系統(tǒng)架構(gòu)無關(guān)。

  • 服務(wù)的一些謬論

  • 解耦合的謬論:服務(wù)強耦合于數(shù)據(jù)結(jié)構(gòu)

  • 獨立開發(fā)的謬論:大型系統(tǒng)一樣可以采用單體模式,或者組件模式來構(gòu)建,不一定非得服務(wù)化。

  • 系統(tǒng)的架構(gòu)是由系統(tǒng)內(nèi)部的架構(gòu)邊界,以及邊界之間的依賴關(guān)系所定義的,與系統(tǒng)中各組件之間的調(diào)用和通信方式無關(guān)。

測試邊界

  • 測試代碼也是系統(tǒng)的一部分
  • 測試代碼始終都是向內(nèi)依賴于被測試部分的代碼,而且系統(tǒng)中沒有其他組件依賴于它們。
  • 如果測試代碼與系統(tǒng)是強耦合的,它就得隨著系統(tǒng)變更而變更。修改以嘎通用的系統(tǒng)組件可能會導(dǎo)致成千上百個測試出現(xiàn)問題,我們通常將這類問題稱為脆弱的測試問題(fragile tests problem)
  • 軟件設(shè)計的第一條原則:不要依賴于多變的東西

整潔的嵌入式架構(gòu)

  • 在軟件和固件之間添加硬件抽象層(HAL),使得硬件發(fā)生變化時,軟件代碼仍能使用

第6部分:實現(xiàn)細節(jié)

數(shù)據(jù)庫只是實現(xiàn)細節(jié)

  • 數(shù)據(jù)的組織結(jié)構(gòu),數(shù)據(jù)的模型,都是系統(tǒng)架構(gòu)中的重要部分,但是從磁盤上存儲/讀取數(shù)據(jù)的機制和手段卻沒那么重要。

web是實現(xiàn)細節(jié)

  • GUI只是一個實現(xiàn)細節(jié)。而Web則是GUI的一種,所以也是一種實現(xiàn)細節(jié)。作為一名軟件架構(gòu)師,我們需要將這類細節(jié)與核心業(yè)務(wù)邏輯隔離開來。

應(yīng)用程序框架是實現(xiàn)細節(jié)

  • 使用框架的風險

  • 框架自身的架構(gòu)設(shè)計很多時候并不是特別正確

  • 隨著產(chǎn)品的成熟,功能要求很可能超出框架所能提供的范圍

  • 框架本身可能朝著我們不需要的方向演進

  • 未來我們可能會想要切換到一個更新、更好的框架上

  • 框架作為架構(gòu)最外圈的一個實現(xiàn)細節(jié)來使用,不要讓它們進入內(nèi)圈

拾遺

  • 本章由Simon Brown撰寫
  • 四種封裝方式的訪問限制(從左到右分別是按層封裝、按功能封裝、端口和適配器、按組件封裝)。
1660058599511-81314f11-48a2-4646-ab81-8a72a6e53895.png
  • Simon Brown對組件的定義是

在一個執(zhí)行環(huán)境(應(yīng)用程序)中的、一個干凈、良好的接口背后的一系列相關(guān)功能的結(jié)合。

與Bob大叔的定義稍有不同

組件是部署單元。組件是系統(tǒng)中能夠部署的最小單位,對應(yīng)在java里就是jar文件。

?著作權(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)容

  • 1.設(shè)計與架構(gòu)究竟是什么: 軟件架構(gòu)的終極目標,用最小的人力成本來滿足構(gòu)建和維護該系統(tǒng)的需求。 2.架構(gòu)的兩個價值...
    飛天的龍王閱讀 795評論 0 0
  • 1、程序員的3個層次 1.1、普通程序員 a、編寫代碼:正確處理業(yè)務(wù)流程和數(shù)據(jù)計算;b、讓代碼跑起來 1.2、工程...
    wantao123閱讀 833評論 0 6
  • 本文是《架構(gòu)整潔之道》的讀書心得,作者將書中內(nèi)容拆解后再組織,不僅加入了個人的獨到見解,而且用一張詳細的知識脈絡(luò)圖...
    程序員小2閱讀 269評論 0 1
  • 序 程序員的三個層次(1) 普通程序員編寫代碼,能夠讓程序跑起來的人。(2) 工程師有“潔癖”、有工匠精神、有修養(yǎng)...
    nimw閱讀 1,783評論 0 3
  • 目錄 程序員的三個層次:普通程序員(會編寫代碼,即能讓程序跑起來,能正確地處理業(yè)務(wù)流程和對數(shù)據(jù)進行計算)、工程師(...
    496f92d634c1閱讀 2,743評論 0 1

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