中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
軟件架構(gòu)設(shè)計的核心:抽象與模型、“戰(zhàn)略編程”

0. 引子:人類怎樣應(yīng)對復(fù)雜性?

復(fù)雜性

在任何程序(可以向外延伸到其他很多領(lǐng)域)的生命周期中,復(fù)雜性都會不可避免地增加。
程序越大,工作的人越多,管理復(fù)雜性就越困難,程序員在修改系統(tǒng)時將所有相關(guān)因素牢記在心中變得越來越難;這會減慢開發(fā)速度并導(dǎo)致錯誤,從而進一步延緩開發(fā)速度并增加成本。

很多大型系統(tǒng)的本質(zhì)問題是復(fù)雜性問題,數(shù)百個甚至更多的微服務(wù)相互調(diào)用/依賴,組成一個組件數(shù)量大、行為復(fù)雜、時刻在變動(發(fā)布、配置變更)當(dāng)中的動態(tài)的、復(fù)雜的系統(tǒng)。

如果,我們將領(lǐng)域問題的復(fù)雜度與技術(shù)細節(jié)的復(fù)雜度混合在了一起,這最終將導(dǎo)致——整體復(fù)雜度的指數(shù)級增長。

復(fù)雜性的一個衡量維度:

  • 可維護性/可修改性
  • 一致性
  • 可讀性/清晰性
  • 可測試性

降低系統(tǒng)復(fù)雜性:一致性

Singe Source of Truth(SSO)

一致性是降低系統(tǒng)復(fù)雜性并使其行為更明顯的強大工具。如果系統(tǒng)是一致的,則意味著相似的事情以相似的方式完成,而不同的事情則以不同的方式完成。一致性會產(chǎn)生認知影響力:一旦您了解了某個地方的工作方式,就可以使用該知識立即了解其他使用相同方法的地方。如果系統(tǒng)的實施方式不一致,則開發(fā)人員必須分別了解每種情況。這將花費更多時間。

一致性減少了錯誤。如果系統(tǒng)不一致,則實際上兩種情況可能不同,但兩種情況可能看起來相同。開發(fā)人員可能會看到一個看起來很熟悉的模式,并根據(jù)以前對該模式的遭遇做出錯誤的假設(shè)。另一方面,如果系統(tǒng)是一致的,則基于熟悉情況的假設(shè)將是安全的。一致性允許開發(fā)人員以更少的錯誤來更快地工作。

一致性是投資心態(tài)的另一個例子。確保一致性的工作將需要一些額外的工作:確定約定,創(chuàng)建自動檢查程序,尋找類似情況以模仿新代碼,以及進行代碼審查以教育團隊。這項投資的回報是您的代碼將更加明顯。開發(fā)人員將能夠更快,更準(zhǔn)確地了解代碼的行為,這將使他們能夠以更少的錯誤來更快地工作。

一致性示例

一致性可以應(yīng)用于系統(tǒng)中的許多級別。這里有一些例子。

編碼樣式。如今,開發(fā)組織通常擁有樣式指南,這些樣式指南將程序結(jié)構(gòu)限制在編譯器所強制執(zhí)行的規(guī)則之外?,F(xiàn)代風(fēng)格指南解決了一系列問題,例如縮進,大括號放置,聲明順序,命名,注釋以及對認為危險的語言功能的限制。樣式指南使代碼更易于閱讀,并且可以減少某些類型的錯誤。
接口。具有多個實現(xiàn)的接口是一致性的另一個示例。一旦了解了接口的一種實現(xiàn),其他任何實現(xiàn)都將變得更易于理解,因為您已經(jīng)知道它將必須提供的功能。
設(shè)計模式。設(shè)計模式是某些常見問題的普遍接受的解決方案,例如用于用戶界面設(shè)計的模型視圖控制器方法。如果您可以使用現(xiàn)有的設(shè)計模式來解決問題,則實現(xiàn)會更快地進行,更有可能起作用,并且您的代碼對讀者來說也會更明顯。
不變量。不變式是始終為真的變量或結(jié)構(gòu)的屬性。例如,存儲文本行的數(shù)據(jù)結(jié)構(gòu)可能會強制要求每行以換行符終止。不變式減少了代碼中必須考慮的特殊情況的數(shù)量,并使推理行為的方式變得更加容易。

確保一致性

一致性很難維護,尤其是當(dāng)許多人長時間從事一個項目時。一組人可能不了解另一組中建立的約定。新來者不了解規(guī)則,因此他們無意間違反了約定并創(chuàng)建了與現(xiàn)有約定沖突的新約定。以下是建立和保持一致性的一些技巧:

  • 文檔規(guī)范。創(chuàng)建一個列出最重要的總體約定的文檔,例如編碼樣式準(zhǔn)則。將文檔放置在開發(fā)人員可能會看到的位置,例如項目 Wiki 上的顯眼位置。鼓勵新成員加入小組閱讀文檔,并鼓勵現(xiàn)有人員不時審閱該文檔。Web 上已經(jīng)發(fā)布了來自各個組織的一些樣式指南;考慮從其中之一開始。對于局部性更強的約定,例如不變式,請在代碼中找到合適的位置進行記錄。如果您不寫下約定,那么其他人不太可能會遵循它們。
  • 執(zhí)行機制。即使有好的文檔,開發(fā)人員也很難記住所有約定。實施約定的最佳方法是編寫一個檢查違規(guī)的工具,并確保除非通過檢查程序,否則代碼無法提交到存儲庫。自動檢查器對于底層語法約定特別有用。

1. 模型:抽象與分層

“無名,萬物之始也; 有名,萬物之母也”。(老子的《道德經(jīng)》第一章)
譯文:無,可以用來表示天地渾沌未開之際的狀況,而有,則是宇宙萬物產(chǎn)生之本原的命
名。

抽象(Abstraction)

抽象的使用是計算機科學(xué)中最為重要的概念之一。例如,為一組函數(shù)規(guī)定一個簡單的應(yīng)用程序接口(API)就是一個很好的編程習(xí)慣,程序員無需了解它內(nèi)部的工作便可以使用這些代碼。不同的編程語言提供不同形式和等級的抽象支持,例如 Java 類的聲明和 C 語言的函數(shù)原型。操作系統(tǒng)中也存在著很多的抽象:

在處理器里,指令集結(jié)構(gòu)提供了對實際處理器硬件的抽象。使用這個抽象,機器代碼程序表現(xiàn)得就好像它是運行在一個一次只執(zhí)行一條指令的處理器上。底層的硬件比抽象描述的要復(fù)雜精細得多,它并行地執(zhí)行多條指令,但又總是與那個簡單有序的模型保持一致。只要執(zhí)行模型一樣,不同的處理器實現(xiàn)也能執(zhí)行同樣的機器代碼,而又提供不同的開銷和性能。

文件是對 IO 的抽象,虛擬存儲器是對程序存儲器的抽象,而進程是對一個正在運行的程序的抽象。我們再增加一個新的抽象:虛擬機,它提供對整個計算機(包括操作系統(tǒng)、處理器和程序)的抽象。虛擬機的思想是 IBM 在 20 世紀(jì) 60 年代提出來的,但是最近才顯示出其管理計算機方式上的優(yōu)勢,因為一些計算機必須能夠運行為不同操作系統(tǒng)(例如,Microsoft Windows、MacOS 和 Linux)或同一操作系統(tǒng)的不同版本而設(shè)計的程序。

模塊化設(shè)計

抽象與模塊化設(shè)計的思想緊密相關(guān)。抽象是實體的簡化視圖,其中省略了不重要的細節(jié)。抽象是有用的,因為它們使我們更容易思考和操縱復(fù)雜的事物。在模塊化編程中,每個模塊以其接口的形式提供抽象。該接口提供了模塊功能的簡化視圖;從模塊抽象的角度來看,實現(xiàn)的細節(jié)并不重要,因此在接口中將其省略。

在抽象的定義中,“無關(guān)緊要”一詞至關(guān)重要。從抽象中忽略的不重要的細節(jié)越多越好。但是,如果細節(jié)不重要,則只能將其從抽象中省略。常見的不當(dāng)抽象可能包含以下兩種:

首先,它可以包含并非真正重要的細節(jié)。當(dāng)這種情況發(fā)生時,它會使抽象變得不必要的復(fù)雜,從而增加了使用抽象的開發(fā)人員的認知負擔(dān)。
第二個錯誤是抽象忽略了真正重要的細節(jié)。這導(dǎo)致模糊不清:僅查看抽象的開發(fā)人員將不會獲得正確使用抽象所需的全部信息。忽略重要細節(jié)的抽象是錯誤的抽象:它可能看起來很簡單,但實際上并非如此。
例如,考慮一個文件系統(tǒng)。文件系統(tǒng)提供的抽象省略了許多細節(jié),例如用于選擇存儲設(shè)備上的哪些塊用于給定文件中的數(shù)據(jù)的機制。這些詳細信息對于文件系統(tǒng)的用戶而言并不重要(只要系統(tǒng)提供足夠的性能即可)。但是,文件系統(tǒng)實現(xiàn)的一些細節(jié)對用戶很重要。大多數(shù)文件系統(tǒng)將數(shù)據(jù)緩存在主內(nèi)存中,并且它們可能會延遲將新數(shù)據(jù)寫入存儲設(shè)備以提高性能。一些應(yīng)用程序(例如數(shù)據(jù)庫)需要確切地知道何時將數(shù)據(jù)寫入存儲設(shè)備,因此它們可以確保在系統(tǒng)崩潰后將保留數(shù)據(jù)。因此,將數(shù)據(jù)刷新到輔助存儲的規(guī)則必須在文件系統(tǒng)的接口中可見。

我們不僅依靠抽象來管理復(fù)雜性,而且不僅在編程中,而且在日常生活中無處不在。微波爐包含復(fù)雜的電子設(shè)備,可將交流電轉(zhuǎn)換為微波輻射并將該輻射分布到整個烹飪腔中。幸運的是,用戶看到了一個簡單得多的抽象,它由幾個按鈕控制微波的定時和強度。汽車提供了一種簡單的抽象概念,使我們可以在不了解電動機,電池電源管理,防抱死制動,巡航控制等機制的情況下駕駛它們。

分層存儲模型

另外一個典型的抽象模型,就是計算機的存儲管理模型。

我們知道,在由半導(dǎo)體器件、電路板組成的計算硬件體系中,根本沒有操作系統(tǒng)、TCP/IP、內(nèi)存分配、垃圾回收等等概念模型。聰明的人類(這些人通常就是計算機科學(xué)家了),就是靠著杰出的想象力與抽象能力,設(shè)計出了計算機存儲分層抽象模型:

一個32位操作系統(tǒng)的例子。其中,1GB為操作系統(tǒng)的內(nèi)核空間,用戶無法更改,這部分不用管它;剩下的3GB位用戶的內(nèi)存空間,這是供用戶程序使用的。

分層(Layering)

想必,分層是宇宙創(chuàng)造萬物的方式。從地球構(gòu)造到雞蛋構(gòu)造,從太陽系組成到細胞結(jié)構(gòu),無不如此。

地球分層構(gòu)造圖:

雞蛋結(jié)構(gòu)圖:

太陽系:

細胞結(jié)構(gòu):

操作系統(tǒng)分層圖:

軟件系統(tǒng)由層組成,其中較高的層使用較低層提供的功能。例如:

在文件系統(tǒng)中,最上層實現(xiàn)文件抽象。文件由可變長度的字節(jié)數(shù)組組成,可以通過讀寫可變長度的字節(jié)范圍來更新該字節(jié)。文件系統(tǒng)的下一個下一層在固定大小的磁盤塊的內(nèi)存中實現(xiàn)了高速緩存。調(diào)用者可以假定經(jīng)常使用的塊將保留在內(nèi)存中,以便可以快速訪問它們。最低層由設(shè)備驅(qū)動程序組成,它們在輔助存儲設(shè)備和內(nèi)存之間移動塊。

在諸如 TCP 的網(wǎng)絡(luò)傳輸協(xié)議中,最頂層提供的抽象是從一臺機器可靠地傳遞到另一臺機器的字節(jié)流。此級別在較低級別上構(gòu)建,該級別可以盡最大努力在計算機之間傳輸有限大小的數(shù)據(jù)包:大多數(shù)數(shù)據(jù)包將成功交付,但某些數(shù)據(jù)包可能會丟失或亂序交付。

網(wǎng)絡(luò)分層協(xié)議

從最底層的物理鏈路層層層向上封裝抽象,解決了復(fù)雜的網(wǎng)絡(luò)通信的問題。同樣的,任何復(fù)雜的問題,通過分層最終總能夠回歸最本質(zhì)、最簡單。

DDD 領(lǐng)域分層架構(gòu)

DDD 分層架構(gòu)遵循了“關(guān)注點分離”原則,將屬于業(yè)務(wù)邏輯的關(guān)注點放到:
1、領(lǐng)域?qū)樱―omain Layer)中,
2、而將支撐業(yè)務(wù)邏輯的技術(shù)實現(xiàn)放到基礎(chǔ)設(shè)施層(Infrastructure Layer)中。
3、應(yīng)用層(Application Layer),扮演了雙重角色。一方面它作為業(yè)務(wù)邏輯的外觀(Facade),暴露了能夠體現(xiàn)業(yè)務(wù)用例的應(yīng)用服務(wù)接口;另一方面它又是業(yè)務(wù)邏輯與技術(shù)實現(xiàn)的粘合劑,實現(xiàn)二者之間的協(xié)作。

下圖“分層架構(gòu)“展現(xiàn)的就是一個典型的領(lǐng)域驅(qū)動設(shè)計分層架構(gòu)。藍色區(qū)域的內(nèi)容與業(yè)務(wù)邏輯有關(guān),灰色區(qū)域的內(nèi)容與技術(shù)實現(xiàn)有關(guān),二者涇渭分明,然后匯合在應(yīng)用層。應(yīng)用層確定了業(yè)務(wù)邏輯與技術(shù)實現(xiàn)的邊界,通過直接依賴或者依賴注入(DI,Dependency Injection)的方式將二者結(jié)合起來。

從上到下的層次隔離

為了將我們的應(yīng)用部署到服務(wù)器上,我們需要為其配置一個運行環(huán)境。從底層到頂層有這樣的運行環(huán)境及容器:

  1. 隔離硬件:虛擬機
  2. 隔離操作系統(tǒng):容器虛擬化
  3. 隔離底層:Servlet 容器
  4. 隔離依賴版本:虛擬環(huán)境
  5. 隔離運行環(huán)境:語言虛擬機
  6. 隔離語言:DSL

實現(xiàn)上這是一個請求的處理過程,一個 HTTP 請求會先到達你的主機。如果你的主機上運行著多個虛擬機實例,那么請求就會來到這個虛擬機上。又或者是如果你是在 Docker 這一類容器里運行你的程序的話,那么也會先到達 Docker。隨后這個請求就會交由 HTTP 服務(wù)器來處理,如 Apache、Nginx,這些 HTTP 服務(wù)器再將這些請求交由對應(yīng)的應(yīng)用或腳本來處理。隨后將交由語言底層的指令來處理。

2.靜態(tài)視角:結(jié)構(gòu)

從結(jié)構(gòu)開始

什么是結(jié)構(gòu)(Structure)?結(jié)構(gòu),是由組成整體的各部分的搭配和安排。古人寫毛筆字,有云:“結(jié)構(gòu)圓備如篆法,飄颺灑落如章草?!保〞x·衛(wèi)夫人《筆陣圖》)現(xiàn)代人做軟件結(jié)構(gòu)設(shè)計,依然追尋著這樣一種美感——簡潔、優(yōu)雅、小巧玲瓏若珍珠寶石一般的美。

在軟件架構(gòu)領(lǐng)域,“結(jié)構(gòu)”包括軟件元素,它們之間的關(guān)系,元素和關(guān)系的屬性,以及每個元素的引入和配置的基本原理(ISO/IEC 42010:20072)。

這里定義了架構(gòu)的三要素:職責(zé)明確的模塊或者組件、組件間明確的關(guān)聯(lián)關(guān)系、約束和指導(dǎo)原則。

軟件系統(tǒng)的架構(gòu)是一種隱喻,類似于建筑物的體系結(jié)構(gòu),是一種整體與局部關(guān)系的抽象描述,架構(gòu)是軟件系統(tǒng)內(nèi)部設(shè)計中最重要而又模糊的方面。有系統(tǒng)的地方就需要架構(gòu),大到航空飛機,小到一個電商系統(tǒng)里面的一個功能組件,都需要設(shè)計和架構(gòu)。

架構(gòu),
(1)是對系統(tǒng)中的實體,以及實體之間的關(guān)系,所進行的抽象描述,
(2)是對事物的功能與形式元素之間的對應(yīng)關(guān)系,所做的分配,
(3)是對元素之間的關(guān)系,以及元素同周邊環(huán)境之間的關(guān)系所做的定義。

架構(gòu)能將目標(biāo)系統(tǒng)按某個原則進行切分,切分的原則,是要便于不同的角色進行并行工作,結(jié)構(gòu)良好的創(chuàng)造活動要優(yōu)于毫無結(jié)構(gòu)的創(chuàng)造活動。

為什么需要架構(gòu)?

舉一個蓋房子的例子。我們偶爾會從新聞上聽到某某房子倒塌、高架塌陷等悲慘事件,但是想想背后的原因,是不是因為房子、橋梁結(jié)構(gòu)不合理,施工偷工減料,質(zhì)量檢查沒有履行職責(zé)等原因?qū)е拢?/span>

這個在軟件工程領(lǐng)域,道理是相通的。一個沒有經(jīng)過合理設(shè)計就匆忙開發(fā)上線的系統(tǒng),遲早要還“技術(shù)債”。

架構(gòu)并不由系統(tǒng)的功能決定,而是由系統(tǒng)的非功能屬性決定。

架構(gòu)需要:
1、控制系統(tǒng)復(fù)雜性,將核心業(yè)務(wù)邏輯和技術(shù)細節(jié)的分離與解耦。
2、保證系統(tǒng)高可用。
3、提升團隊整體的研發(fā)效能。

架構(gòu)師的職責(zé)是:
1、努力訓(xùn)練自己的思維,用它去理解復(fù)雜的系統(tǒng),
2、通過合理的分解和抽象,理解并解析需求,
3、創(chuàng)建有用的模型,
4、確認、細化并擴展模型,管理架構(gòu);
5、進行系統(tǒng)分解形成整體架構(gòu),
6、能夠正確的技術(shù)選型,
7、能夠制定技術(shù)規(guī)格說明并有效推動實施落地。

3.動態(tài)視角:運動變化的關(guān)系

戰(zhàn)略與戰(zhàn)術(shù):動態(tài)演化的視角

大多數(shù)程序員的編程行為,都是戰(zhàn)術(shù)思維方式,著眼于使功能盡快運行。
但是,如果您想要一個好的設(shè)計,則必須采取更具戰(zhàn)略性的方法,在此上花費時間來制作干凈的設(shè)計并解決問題。

戰(zhàn)術(shù)編程(Tactical Programming)

在戰(zhàn)術(shù)編程方法中,核心關(guān)注點是,使某些功能正常工作,例如新功能或錯誤修復(fù)。
乍一看,這似乎是完全合理的:還有什么比編寫有效的代碼更重要的呢?
但是,戰(zhàn)術(shù)編程幾乎不可能產(chǎn)生出良好的系統(tǒng)設(shè)計。
戰(zhàn)術(shù)編程的問題是它是短視的。
如果您是戰(zhàn)術(shù)編程人員,那么您將只是盡快完成任務(wù),您不會花費太多時間來尋找最佳設(shè)計。您只想盡快使某件事起作用。您告訴自己,可以增加一些復(fù)雜性或引入一兩個小錯誤,如果這樣可以使當(dāng)前任務(wù)更快地完成,則可以。

如果您進行戰(zhàn)術(shù)編程,則每個編程任務(wù)都會帶來一些此類復(fù)雜性。
為了快速完成當(dāng)前任務(wù),他們每個人似乎都是一個合理的折衷方案。
但是,復(fù)雜性迅速累積,尤其是如果每個人都在戰(zhàn)術(shù)上進行編程的時候。

不久之后,某些復(fù)雜性將開始引起問題,但是,您會告訴(qi pian)自己,使下一個功能正常工作比返回并重構(gòu)現(xiàn)有代碼更為重要。從長遠來看,重構(gòu)可能會有所幫助,但是肯定會減慢當(dāng)前的任務(wù)。

因此,您需要快速修補程序來解決遇到的任何問題。這只會增加復(fù)雜性,然后需要更多補丁。

很快代碼變得一團糟,但是到現(xiàn)在為止,情況已經(jīng)很糟糕了,清理它需要花費數(shù)月的時間。您的日程安排無法容忍這種延遲,解決一個或兩個問題似乎并沒有太大的區(qū)別,因此您只是在戰(zhàn)術(shù)上保持編程。

幾乎每個軟件開發(fā)組織,都有至少一個將戰(zhàn)術(shù)編程發(fā)揮到極致的開發(fā)人員:戰(zhàn)術(shù)龍卷風(fēng)(The tactical tornado)。

戰(zhàn)術(shù)龍卷風(fēng)是一位多產(chǎn)的程序員,他抽出代碼的速度比其他人快得多,但完全以戰(zhàn)術(shù)方式工作。實施快速功能時,沒有人能比戰(zhàn)術(shù)龍卷風(fēng)更快地完成任務(wù)。

在某些組織中,管理層將戰(zhàn)術(shù)龍卷風(fēng)視為英雄。但是,戰(zhàn)術(shù)龍卷風(fēng)留下了毀滅的痕跡。他們很少被將來必須使用其代碼的工程師視為英雄。通常,其他工程師必須清理戰(zhàn)術(shù)龍卷風(fēng)留下的混亂局面,這使得那些工程師(他們是真正的英雄)的進步似乎比戰(zhàn)術(shù)龍卷風(fēng)慢。

在戰(zhàn)術(shù)編程中,您將不斷增加一些復(fù)雜性,這些復(fù)雜性將來會引起問題。

戰(zhàn)略編程(Strategic programming)

成為一名優(yōu)秀的軟件設(shè)計師的第一步是要意識到僅工作代碼是不夠的。引入不必要的復(fù)雜性以更快地完成當(dāng)前任務(wù)是不可接受的。最重要的是系統(tǒng)的長期結(jié)構(gòu)。任何系統(tǒng)中的大多數(shù)代碼都是通過擴展現(xiàn)有代碼庫編寫的,因此,作為開發(fā)人員,最重要的工作就是促進這些將來的擴展。因此,盡管您的代碼當(dāng)然必須工作,但您不應(yīng)將“工作代碼”視為主要目標(biāo)。您的主要目標(biāo)必須是制作出出色的設(shè)計,并且這種設(shè)計也會起作用。這是戰(zhàn)略計劃。

戰(zhàn)略性編程需要一種投資心態(tài)。您必須花費時間來改進系統(tǒng)的設(shè)計,而不是采取最快的方式來完成當(dāng)前的項目。這些投資會在短期內(nèi)讓您放慢腳步,但從長遠來看會加快您的速度。一些投資將是積極的。例如,值得花一些時間為每個新類找到一個簡單的設(shè)計。而不是實施想到的第一個想法,請嘗試幾種替代設(shè)計并選擇最簡潔的設(shè)計。試想一下將來可能需要更改系統(tǒng)的幾種方式,并確保設(shè)計容易。編寫好的文檔是主動投資的另一個例子。

如果您進行戰(zhàn)略性編程,則將不斷對系統(tǒng)設(shè)計進行小幅改進。

權(quán)衡:ROI

一開始,戰(zhàn)術(shù)性的編程方法將比戰(zhàn)略性方法更快地取得進展。但是,在戰(zhàn)術(shù)方法下,復(fù)雜性積累得更快,從而降低了生產(chǎn)率。

隨著時間的流逝,戰(zhàn)略方針會帶來更大的進步。注意:此圖僅用于定性說明;我不知道對曲線精確形狀的任何經(jīng)驗測量。

相反,如果您進行戰(zhàn)術(shù)編程,則可以將第一個項目完成的速度提高 10%到 20%,但是隨著時間的推移,復(fù)雜性的累積會降低開發(fā)速度。不久之后,您的編程速度至少會降低 10–20%。您將很快退回在開始時節(jié)省的所有時間,并且在系統(tǒng)的整個生命周期中,與采用策略性方法相比,您的開發(fā)速度將更加緩慢。

可持續(xù)迭代演化的系統(tǒng):演進式架構(gòu)(Evolutionary Architecture)

與傳統(tǒng)的前期、重量級的企業(yè)架構(gòu)設(shè)計相比,我們建議采用演進式架構(gòu)(Evolutionary Architecture)。它提供了企業(yè)架構(gòu)的好處,卻沒有試圖準(zhǔn)確預(yù)測未來所帶來的問題。

演進式架構(gòu)不需要猜測組件將如何被重用,而是支持適應(yīng)性,使用適當(dāng)?shù)某橄?、?shù)據(jù)庫遷移、測試套件、持續(xù)集成和重構(gòu)來收獲系統(tǒng)內(nèi)發(fā)生的重用。

盡管我們盡了最大努力,但復(fù)雜度仍會隨著時間的推移而增加,但是更簡單的設(shè)計使我們能夠在復(fù)雜性壓倒性優(yōu)勢之前構(gòu)建更大,功能更強大的系統(tǒng)。復(fù)雜性的應(yīng)對永遠不會是一勞永逸,我們需要不斷地推陳出新,是動態(tài)、漸進的重塑自己對軟件系統(tǒng)的認識,不斷認識問題和尋找更優(yōu)解的持續(xù)迭代:

互聯(lián)網(wǎng)行業(yè)的軟件系統(tǒng),很難一開始就做出完美的設(shè)計,通過一個個功能模塊衍生迭代,系統(tǒng)才會逐步成型;對于現(xiàn)存的系統(tǒng),也很難通過一個大動作,一勞永逸地解決所有問題。系統(tǒng)設(shè)計是需要持續(xù)投入的工作,通過細節(jié)的積累,最終得到一個完善的系統(tǒng)。因此,好的設(shè)計是日拱一卒的結(jié)果,在日常工作中要重視設(shè)計和細節(jié)的改進。

  1. 通過使代碼更簡單和更清晰(Obvious)來消除復(fù)雜性。例如: 減少特殊場景的處理,或變量命名一致性都能降低系統(tǒng)復(fù)雜性。代碼能夠描述程序的工作流程和結(jié)果,卻很難描述開發(fā)人員的思路,而注釋和文檔可以。此外,通過注釋和文檔,開發(fā)人員在不閱讀實現(xiàn)代碼的情況下,就可以理解程序的功能,注釋間接促成了代碼抽象。好的注釋能夠幫助解決軟件復(fù)雜性問題,尤其是認知負擔(dān)和不可知問題(Unknown Unknowns)。
  2. 通過分層或者分模塊來封裝它,對復(fù)雜問題的抽象然后分而治之,以便程序員可以在系統(tǒng)上工作而不會立即暴露其所有復(fù)雜性。這種方法稱為模塊化設(shè)計。在模塊化設(shè)計中,軟件系統(tǒng)分為模塊,例如面向?qū)ο笳Z言的類。這些模塊被設(shè)計為彼此相對獨立,以便程序員可以在一個模塊上工作而不必了解其他模塊的細節(jié)。
  3. 專業(yè)化分工和代碼復(fù)用,促成了軟件生產(chǎn)率的提升。比如硬件工程師、軟件工程師(底層、應(yīng)用、不同編程語言)可以在無需了解對方技術(shù)背景的情況下進行合作開發(fā);同一領(lǐng)域服務(wù)可以支撐不同的上層應(yīng)用邏輯等等。其背后的思想,無非是通過將系統(tǒng)分成若干個水平層、明確每一層的角色和分工,來降低單個層次的復(fù)雜性。同時,每個層次只要給相鄰層提供一致的接口,可以用不同的方法實現(xiàn),這就為軟件重用提供了支持。分層是解決復(fù)雜性問題的重要原則。
  4. 與分層類似,分模塊是從垂直方向來分解系統(tǒng)。分模塊最常見的應(yīng)用場景,是如今廣泛流行的微服務(wù)。分模塊降低了單模塊的復(fù)雜性,但是也會引入新的復(fù)雜性,例如模塊與模塊的交互

4. 軟件架構(gòu)編年史

  • 20 世紀(jì) 50 年代非結(jié)構(gòu)化編程~1951 – 匯編
  • 20 世紀(jì) 60 年代結(jié)構(gòu)化編程分層: 用戶界面、業(yè)務(wù)邏輯數(shù)據(jù)存儲都在一層。~1958 – Algol
  • 20 世紀(jì) 70 年代過程式/函數(shù)式編程~1970 – Pascal~1972 – C1979 – MVC 模式(Model-View-Controller)
  • 20 世紀(jì) 80 年代面向?qū)ο缶幊?/span> (但其思想在 20 世紀(jì) 60 年代晚期已經(jīng)第一次提出)分層: 兩層,第一層是用戶界面,第二層是業(yè)務(wù)邏輯和數(shù)據(jù)存儲~1980 – C++CORBA – 通用物件請求代理架構(gòu)(盡管1991 年才推出第一個穩(wěn)定版,但最早使用可以追溯到 20 世紀(jì) 80 年代)~1986 – Erlang~1987 – Perl1987 – PAC 即 HMVC 模式(Hierarchical Model-View-Controller)1988 – LSP(里氏替換原則) (~SOLID)
  • 20 世紀(jì) 90 年代分層: 三層,第一層是用戶界面,第二層是業(yè)務(wù)邏輯(以及瀏覽器作為客戶端時的用戶界面展現(xiàn)邏輯),第三層是數(shù)據(jù)存儲~1991 – 消息總線~1991 – Python1992 – EBI 架構(gòu)(Entity-Boundary-Interactor) 即 EBC 或 EIC~1993 – Ruby~1995 – Delphi, Java, Javascript, PHP1996 – MVP 模式(Model-View-Presenter)1996 – OCP, ISP, DIP (~SOLID), REP, CRP, CCP, ADP1997 – SDP, SAP~1997 – 面向方面編程~1997 – Web 服務(wù)~1997 – ESB – 企業(yè)服務(wù)總線 (盡管創(chuàng)造該術(shù)語的書籍 2004 年才出版,但這個概念早已被使用)
  • 21 世紀(jì) 00 年代2002 – SRP (~SOLID)2003 – 領(lǐng)域驅(qū)動設(shè)計2005 – MVVM 模式(Model-View-ViewModel)2005 – 端口和適配器架構(gòu)即六邊形架構(gòu)2006 – CQRS 與 ES (命令查詢職責(zé)分離與事件溯源)2008 – 洋蔥架構(gòu)2009 – 微服務(wù)(Netflix)
  • 21 世紀(jì) 10 年代2010 – DCI 架構(gòu)(Data-Context-Interaction)2012 – 整潔架構(gòu)2014 – C4 模型

5. 編程哲學(xué):禪與計算機程序設(shè)計藝術(shù)

美麗勝于丑陋。 顯式優(yōu)于隱式。 簡單勝于復(fù)雜。 復(fù)雜勝于復(fù)雜。 扁平比嵌套好。 疏勝于密。 可讀性很重要。 特殊情況不足以打破規(guī)則。 盡管,實用第一,簡潔第二。 錯誤永遠不應(yīng)該無聲無息地過去。 除非明確沉默。 面對曖昧,拒絕猜測的誘惑。 應(yīng)該有一種——最好只有一種——顯而易見的方法來做到這一點。 雖然這種方式一開始可能不明顯,除非你是荷蘭人。 現(xiàn)在總比沒有好。 雖然永遠不會比現(xiàn)在好。 如果實現(xiàn)很難解釋,那就是一個壞主意。 如果實現(xiàn)容易解釋,這可能是一個好主意。 命名空間是一個非常棒的主意——讓我們做更多這樣的事情吧!Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!

6. 架構(gòu)師

架構(gòu)師,是一個既能掌控整體全局,又能洞悉局部瓶頸,并依據(jù)具體的業(yè)務(wù)場景,給出解決方案的團隊領(lǐng)導(dǎo)型人物。

軟件系統(tǒng)架構(gòu)師綜合的知識能力包括9個方面,即:

1、戰(zhàn)略規(guī)劃能力。

2、業(yè)務(wù)流程建模能力。

3、信息數(shù)據(jù)結(jié)構(gòu)能力。

4、技術(shù)架構(gòu)選擇和實現(xiàn)能力。

5、應(yīng)用系統(tǒng)架構(gòu)的解決和實現(xiàn)能力。

6、基礎(chǔ)IT知識及基礎(chǔ)設(shè)施、資源調(diào)配能力。

7、信息安全技術(shù)支持與管理保障能力。

8、IT審計、治理與基本需求分析、獲取能力。

9、面向軟件系統(tǒng)可靠性與系統(tǒng)生命周期的質(zhì)量保障服務(wù)能力。

作為系統(tǒng)架構(gòu)師,必須成為所在開發(fā)團隊的技術(shù)路線指導(dǎo)者;具有很強的系統(tǒng)思維的能力;需要從大量互相沖突的系統(tǒng)方法和工具中區(qū)分出哪些是有效的,哪些是無效的。架構(gòu)師應(yīng)當(dāng)是一個成熟的、豐富的、有經(jīng)驗的、有良好教育的、學(xué)習(xí)快捷、善溝通和決策能力強的人。豐富是指他必須具有業(yè)務(wù)領(lǐng)域方面的工作知識,知識來源于經(jīng)驗或者教育。他必須廣泛了解各種技術(shù)并精通一種特定技術(shù),至少了解計算機通用技術(shù)以便確定那種技術(shù)最優(yōu),或組織團隊開展技術(shù)評估。優(yōu)秀的架構(gòu)師能考慮并評估所有可用來解決問題的總體技術(shù)方案。需要良好的書面和口頭溝通技巧,一般通過可視化模型和小組討論來溝通指導(dǎo)團隊確保開發(fā)人員按照架構(gòu)建造系統(tǒng)。

具備的能力

(1)技術(shù)能力

技術(shù)能力,不用置疑肯定是最重要的。技術(shù)能力弱的架構(gòu)不是一個好架構(gòu)。所以,你需要知道所有主流技術(shù)的基本原理、應(yīng)用場景,及快速解決問題的能力。所以,架構(gòu)師必須要有見識,所需知識面肯定是要不斷拓展的。你需要清楚在什么樣的場景用什么樣的技術(shù)比較合適,并知道可能存在什么樣的風(fēng)險。來了需求,你腦袋是空的,不知道用什么技術(shù)這是最可怕的。

(2)架構(gòu)能力

這個可以表現(xiàn)為抽象能力、整體規(guī)劃能力、及設(shè)計能力。你需要照在業(yè)務(wù)的角度進行系統(tǒng)分解、技術(shù)選型、架構(gòu)搭建,以及規(guī)范制定。架構(gòu)出來了至少可以滿足最近的發(fā)展,或者可以很方便對現(xiàn)有架構(gòu)進行擴容。有人說架構(gòu)不需要懂業(yè)務(wù),我面試過的就有明確表示不做業(yè)務(wù)架構(gòu)。當(dāng)然有方面的架構(gòu)師,如中間件架構(gòu)師,運維基礎(chǔ)設(shè)施架構(gòu)師等。但一般的后端架構(gòu)師都是需要了解業(yè)務(wù),不理解業(yè)務(wù)你如果進行系統(tǒng)分解,服務(wù)劃分,及根據(jù)不同業(yè)務(wù)作出不同的架構(gòu)。技術(shù)都是為業(yè)務(wù)服務(wù)的,不站在業(yè)務(wù)的角度設(shè)計架構(gòu),那架構(gòu)就是空談。[1]

(3)溝通能力

這個看起來不是最重要的,其實也非常重要。作為一個優(yōu)秀的架構(gòu)師,你需要清楚的知道客戶的需求,需要不斷和需求人員進行溝通,以達到客戶真正的目的。不論是不是架構(gòu)師,任何一個職場人,提高自己的溝通表達能力無疑是不可或缺的。有一句話怎么說的,領(lǐng)導(dǎo)就喜歡拍馬屁的。做領(lǐng)導(dǎo)的大多不是技術(shù)特別牛的,但溝通能力肯定是很好的。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
滴滴出行|海量數(shù)據(jù)背后的高可用架構(gòu)
《軟件設(shè)計的哲學(xué)》解讀
直擊架構(gòu)本質(zhì):優(yōu)秀架構(gòu)師必須掌握的幾種架構(gòu)思維
架構(gòu)之思-分析那些深入骨髓的設(shè)計原則
讓藝術(shù)照亮技術(shù)之美
前端程序員的進階
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服