0. 引子:人類怎樣應對復雜性?
復雜性
在任何程序(可以向外延伸到其他很多領域)的生命周期中,復雜性都會不可避免地增加。
程序越大,工作的人越多,管理復雜性就越困難,程序員在修改系統時將所有相關因素牢記在心中變得越來越難;這會減慢開發速度并導致錯誤,從而進一步延緩開發速度并增加成本。
很多大型系統的本質問題是復雜性問題,數百個甚至更多的微服務相互調用/依賴,組成一個組件數量大、行為復雜、時刻在變動(發布、配置變更)當中的動態的、復雜的系統。
如果,我們將領域問題的復雜度與技術細節的復雜度混合在了一起,這最終將導致——整體復雜度的指數級增長。
復雜性的一個衡量維度:
- 可維護性/可修改性
- 一致性
- 可讀性/清晰性
- 可測試性
降低系統復雜性:一致性
Singe Source of Truth(SSO)
一致性是降低系統復雜性并使其行為更明顯的強大工具。如果系統是一致的,則意味著相似的事情以相似的方式完成,而不同的事情則以不同的方式完成。一致性會產生認知影響力:一旦您了解了某個地方的工作方式,就可以使用該知識立即了解其他使用相同方法的地方。如果系統的實施方式不一致,則開發人員必須分別了解每種情況。這將花費更多時間。
一致性減少了錯誤。如果系統不一致,則實際上兩種情況可能不同,但兩種情況可能看起來相同。開發人員可能會看到一個看起來很熟悉的模式,并根據以前對該模式的遭遇做出錯誤的假設。另一方面,如果系統是一致的,則基于熟悉情況的假設將是安全的。一致性允許開發人員以更少的錯誤來更快地工作。
一致性是投資心態的另一個例子。確保一致性的工作將需要一些額外的工作:確定約定,創建自動檢查程序,尋找類似情況以模仿新代碼,以及進行代碼審查以教育團隊。這項投資的回報是您的代碼將更加明顯。開發人員將能夠更快,更準確地了解代碼的行為,這將使他們能夠以更少的錯誤來更快地工作。
一致性示例
一致性可以應用于系統中的許多級別。這里有一些例子。
編碼樣式。如今,開發組織通常擁有樣式指南,這些樣式指南將程序結構限制在編譯器所強制執行的規則之外。現代風格指南解決了一系列問題,例如縮進,大括號放置,聲明順序,命名,注釋以及對認為危險的語言功能的限制。樣式指南使代碼更易于閱讀,并且可以減少某些類型的錯誤。
接口。具有多個實現的接口是一致性的另一個示例。一旦了解了接口的一種實現,其他任何實現都將變得更易于理解,因為您已經知道它將必須提供的功能。
設計模式。設計模式是某些常見問題的普遍接受的解決方案,例如用于用戶界面設計的模型視圖控制器方法。如果您可以使用現有的設計模式來解決問題,則實現會更快地進行,更有可能起作用,并且您的代碼對讀者來說也會更明顯。
不變量。不變式是始終為真的變量或結構的屬性。例如,存儲文本行的數據結構可能會強制要求每行以換行符終止。不變式減少了代碼中必須考慮的特殊情況的數量,并使推理行為的方式變得更加容易。
確保一致性
一致性很難維護,尤其是當許多人長時間從事一個項目時。一組人可能不了解另一組中建立的約定。新來者不了解規則,因此他們無意間違反了約定并創建了與現有約定沖突的新約定。以下是建立和保持一致性的一些技巧:
- 文檔規范。創建一個列出最重要的總體約定的文檔,例如編碼樣式準則。將文檔放置在開發人員可能會看到的位置,例如項目 Wiki 上的顯眼位置。鼓勵新成員加入小組閱讀文檔,并鼓勵現有人員不時審閱該文檔。Web 上已經發布了來自各個組織的一些樣式指南;考慮從其中之一開始。對于局部性更強的約定,例如不變式,請在代碼中找到合適的位置進行記錄。如果您不寫下約定,那么其他人不太可能會遵循它們。
- 執行機制。即使有好的文檔,開發人員也很難記住所有約定。實施約定的最佳方法是編寫一個檢查違規的工具,并確保除非通過檢查程序,否則代碼無法提交到存儲庫。自動檢查器對于底層語法約定特別有用。
1. 模型:抽象與分層
“無名,萬物之始也; 有名,萬物之母也”。(老子的《道德經》第一章)
譯文:無,可以用來表示天地渾沌未開之際的狀況,而有,則是宇宙萬物產生之本原的命
名。
抽象(Abstraction)
抽象的使用是計算機科學中最為重要的概念之一。例如,為一組函數規定一個簡單的應用程序接口(API)就是一個很好的編程習慣,程序員無需了解它內部的工作便可以使用這些代碼。不同的編程語言提供不同形式和等級的抽象支持,例如 JAVA 類的聲明和 C 語言的函數原型。操作系統中也存在著很多的抽象:
在處理器里,指令集結構提供了對實際處理器硬件的抽象。使用這個抽象,機器代碼程序表現得就好像它是運行在一個一次只執行一條指令的處理器上。底層的硬件比抽象描述的要復雜精細得多,它并行地執行多條指令,但又總是與那個簡單有序的模型保持一致。只要執行模型一樣,不同的處理器實現也能執行同樣的機器代碼,而又提供不同的開銷和性能。
文件是對 IO 的抽象,虛擬存儲器是對程序存儲器的抽象,而進程是對一個正在運行的程序的抽象。我們再增加一個新的抽象:虛擬機,它提供對整個計算機(包括操作系統、處理器和程序)的抽象。虛擬機的思想是 IBM 在 20 世紀 60 年代提出來的,但是最近才顯示出其管理計算機方式上的優勢,因為一些計算機必須能夠運行為不同操作系統(例如,Microsoft windows、macOS 和 linux)或同一操作系統的不同版本而設計的程序。
模塊化設計
抽象與模塊化設計的思想緊密相關。抽象是實體的簡化視圖,其中省略了不重要的細節。抽象是有用的,因為它們使我們更容易思考和操縱復雜的事物。在模塊化編程中,每個模塊以其接口的形式提供抽象。該接口提供了模塊功能的簡化視圖;從模塊抽象的角度來看,實現的細節并不重要,因此在接口中將其省略。
在抽象的定義中,“無關緊要”一詞至關重要。從抽象中忽略的不重要的細節越多越好。但是,如果細節不重要,則只能將其從抽象中省略。常見的不當抽象可能包含以下兩種:
首先,它可以包含并非真正重要的細節。當這種情況發生時,它會使抽象變得不必要的復雜,從而增加了使用抽象的開發人員的認知負擔。
第二個錯誤是抽象忽略了真正重要的細節。這導致模糊不清:僅查看抽象的開發人員將不會獲得正確使用抽象所需的全部信息。忽略重要細節的抽象是錯誤的抽象:它可能看起來很簡單,但實際上并非如此。
例如,考慮一個文件系統。文件系統提供的抽象省略了許多細節,例如用于選擇存儲設備上的哪些塊用于給定文件中的數據的機制。這些詳細信息對于文件系統的用戶而言并不重要(只要系統提供足夠的性能即可)。但是,文件系統實現的一些細節對用戶很重要。大多數文件系統將數據緩存在主內存中,并且它們可能會延遲將新數據寫入存儲設備以提高性能。一些應用程序(例如數據庫)需要確切地知道何時將數據寫入存儲設備,因此它們可以確保在系統崩潰后將保留數據。因此,將數據刷新到輔助存儲的規則必須在文件系統的接口中可見。
我們不僅依靠抽象來管理復雜性,而且不僅在編程中,而且在日常生活中無處不在。微波爐包含復雜的電子設備,可將交流電轉換為微波輻射并將該輻射分布到整個烹飪腔中。幸運的是,用戶看到了一個簡單得多的抽象,它由幾個按鈕控制微波的定時和強度。汽車提供了一種簡單的抽象概念,使我們可以在不了解電動機,電池電源管理,防抱死制動,巡航控制等機制的情況下駕駛它們。
分層存儲模型
另外一個典型的抽象模型,就是計算機的存儲管理模型。
我們知道,在由半導體器件、電路板組成的計算硬件體系中,根本沒有操作系統、TCP/IP、內存分配、垃圾回收等等概念模型。聰明的人類(這些人通常就是計算機科學家了),就是靠著杰出的想象力與抽象能力,設計出了計算機存儲分層抽象模型:
一個32位操作系統的例子。其中,1GB為操作系統的內核空間,用戶無法更改,這部分不用管它;剩下的3GB位用戶的內存空間,這是供用戶程序使用的。
分層(Layering)
想必,分層是宇宙創造萬物的方式。從地球構造到雞蛋構造,從太陽系組成到細胞結構,無不如此。
地球分層構造圖:
雞蛋結構圖:
太陽系:
細胞結構:
操作系統分層圖:
軟件系統由層組成,其中較高的層使用較低層提供的功能。例如:
在文件系統中,最上層實現文件抽象。文件由可變長度的字節數組組成,可以通過讀寫可變長度的字節范圍來更新該字節。文件系統的下一個下一層在固定大小的磁盤塊的內存中實現了高速緩存。調用者可以假定經常使用的塊將保留在內存中,以便可以快速訪問它們。最低層由設備驅動程序組成,它們在輔助存儲設備和內存之間移動塊。
在諸如 TCP 的網絡傳輸協議中,最頂層提供的抽象是從一臺機器可靠地傳遞到另一臺機器的字節流。此級別在較低級別上構建,該級別可以盡最大努力在計算機之間傳輸有限大小的數據包:大多數數據包將成功交付,但某些數據包可能會丟失或亂序交付。
網絡分層協議
從最底層的物理鏈路層層層向上封裝抽象,解決了復雜的網絡通信的問題。同樣的,任何復雜的問題,通過分層最終總能夠回歸最本質、最簡單。
DDD 領域分層架構
DDD 分層架構遵循了“關注點分離”原則,將屬于業務邏輯的關注點放到:
1、領域層(Domain Layer)中,
2、而將支撐業務邏輯的技術實現放到基礎設施層(Infrastructure Layer)中。
3、應用層(Application Layer),扮演了雙重角色。一方面它作為業務邏輯的外觀(Facade),暴露了能夠體現業務用例的應用服務接口;另一方面它又是業務邏輯與技術實現的粘合劑,實現二者之間的協作。
下圖“分層架構“展現的就是一個典型的領域驅動設計分層架構。藍色區域的內容與業務邏輯有關,灰色區域的內容與技術實現有關,二者涇渭分明,然后匯合在應用層。應用層確定了業務邏輯與技術實現的邊界,通過直接依賴或者依賴注入(DI,Dependency Injection)的方式將二者結合起來。
從上到下的層次隔離
為了將我們的應用部署到服務器上,我們需要為其配置一個運行環境。從底層到頂層有這樣的運行環境及容器:
- 隔離硬件:虛擬機
- 隔離操作系統:容器虛擬化
- 隔離底層:Servlet 容器
- 隔離依賴版本:虛擬環境
- 隔離運行環境:語言虛擬機
- 隔離語言:DSL
實現上這是一個請求的處理過程,一個 HTTP 請求會先到達你的主機。如果你的主機上運行著多個虛擬機實例,那么請求就會來到這個虛擬機上。又或者是如果你是在 Docker 這一類容器里運行你的程序的話,那么也會先到達 Docker。隨后這個請求就會交由 HTTP 服務器來處理,如 Apache、Nginx,這些 HTTP 服務器再將這些請求交由對應的應用或腳本來處理。隨后將交由語言底層的指令來處理。
2.靜態視角:結構
從結構開始
什么是結構(Structure)?結構,是由組成整體的各部分的搭配和安排。古人寫毛筆字,有云:“結構圓備如篆法,飄颺灑落如章草。”(晉·衛夫人《筆陣圖》)現代人做軟件結構設計,依然追尋著這樣一種美感——簡潔、優雅、小巧玲瓏若珍珠寶石一般的美。
在軟件架構領域,“結構”包括軟件元素,它們之間的關系,元素和關系的屬性,以及每個元素的引入和配置的基本原理(ISO/IEC 42010:20072)。
這里定義了架構的三要素:職責明確的模塊或者組件、組件間明確的關聯關系、約束和指導原則。
軟件系統的架構是一種隱喻,類似于建筑物的體系結構,是一種整體與局部關系的抽象描述,架構是軟件系統內部設計中最重要而又模糊的方面。有系統的地方就需要架構,大到航空飛機,小到一個電商系統里面的一個功能組件,都需要設計和架構。
架構,
(1)是對系統中的實體,以及實體之間的關系,所進行的抽象描述,
(2)是對事物的功能與形式元素之間的對應關系,所做的分配,
(3)是對元素之間的關系,以及元素同周邊環境之間的關系所做的定義。
架構能將目標系統按某個原則進行切分,切分的原則,是要便于不同的角色進行并行工作,結構良好的創造活動要優于毫無結構的創造活動。
為什么需要架構? 舉一個蓋房子的例子。我們偶爾會從新聞上聽到某某房子倒塌、高架塌陷等悲慘事件,但是想想背后的原因,是不是因為房子、橋梁結構不合理,施工偷工減料,質量檢查沒有履行職責等原因導致?
這個在軟件工程領域,道理是相通的。一個沒有經過合理設計就匆忙開發上線的系統,遲早要還“技術債”。
架構并不由系統的功能決定,而是由系統的非功能屬性決定。架構需要:
1、控制系統復雜性,將核心業務邏輯和技術細節的分離與解耦。
2、保證系統高可用。
3、提升團隊整體的研發效能。
架構師的職責是:
1、努力訓練自己的思維,用它去理解復雜的系統,
2、通過合理的分解和抽象,理解并解析需求,
3、創建有用的模型,
4、確認、細化并擴展模型,管理架構;
5、進行系統分解形成整體架構,
6、能夠正確的技術選型,
7、能夠制定技術規格說明并有效推動實施落地。
3.動態視角:運動變化的關系 戰略與戰術:動態演化的視角 大多數程序員的編程行為,都是戰術思維方式,著眼于使功能盡快運行。
但是,如果您想要一個好的設計,則必須采取更具戰略性的方法,在此上花費時間來制作干凈的設計并解決問題。
戰術編程(Tactical%20Programming) 在戰術編程方法中,核心關注點是,使某些功能正常工作,例如新功能或錯誤修復。
乍一看,這似乎是完全合理的:還有什么比編寫有效的代碼更重要的呢?
但是,戰術編程幾乎不可能產生出良好的系統設計。
戰術編程的問題是它是短視的。
如果您是戰術編程人員,那么您將只是盡快完成任務,您不會花費太多時間來尋找最佳設計。您只想盡快使某件事起作用。您告訴自己,可以增加一些復雜性或引入一兩個小錯誤,如果這樣可以使當前任務更快地完成,則可以。
如果您進行戰術編程,則每個編程任務都會帶來一些此類復雜性。
為了快速完成當前任務,他們每個人似乎都是一個合理的折衷方案。
但是,復雜性迅速累積,尤其是如果每個人都在戰術上進行編程的時候。
不久之后,某些復雜性將開始引起問題,但是,您會告訴(qi%20pian)自己,使下一個功能正常工作比返回并重構現有代碼更為重要。從長遠來看,重構可能會有所幫助,但是肯定會減慢當前的任務。
因此,您需要快速修補程序來解決遇到的任何問題。這只會增加復雜性,然后需要更多補丁。
很快代碼變得一團糟,但是到現在為止,情況已經很糟糕了,清理它需要花費數月的時間。您的日程安排無法容忍這種延遲,解決一個或兩個問題似乎并沒有太大的區別,因此您只是在戰術上保持編程。
幾乎每個軟件開發組織,都有至少一個將戰術編程發揮到極致的開發人員:戰術龍卷風(The%20tactical%20tornado)。
戰術龍卷風是一位多產的程序員,他抽出代碼的速度比其他人快得多,但完全以戰術方式工作。實施快速功能時,沒有人能比戰術龍卷風更快地完成任務。
在某些組織中,管理層將戰術龍卷風視為英雄。但是,戰術龍卷風留下了毀滅的痕跡。他們很少被將來必須使用其代碼的工程師視為英雄。通常,其他工程師必須清理戰術龍卷風留下的混亂局面,這使得那些工程師(他們是真正的英雄)的進步似乎比戰術龍卷風慢。
在戰術編程中,您將不斷增加一些復雜性,這些復雜性將來會引起問題。
戰略編程(Strategic%20programming) 成為一名優秀的軟件設計師的第一步是要意識到僅工作代碼是不夠的。引入不必要的復雜性以更快地完成當前任務是不可接受的。最重要的是系統的長期結構。任何系統中的大多數代碼都是通過擴展現有代碼庫編寫的,因此,作為開發人員,最重要的工作就是促進這些將來的擴展。因此,盡管您的代碼當然必須工作,但您不應將“工作代碼”視為主要目標。您的主要目標必須是制作出出色的設計,并且這種設計也會起作用。這是戰略計劃。
戰略性編程需要一種投資心態。您必須花費時間來改進系統的設計,而不是采取最快的方式來完成當前的項目。這些投資會在短期內讓您放慢腳步,但從長遠來看會加快您的速度。一些投資將是積極的。例如,值得花一些時間為每個新類找到一個簡單的設計。而不是實施想到的第一個想法,請嘗試幾種替代設計并選擇最簡潔的設計。試想一下將來可能需要更改系統的幾種方式,并確保設計容易。編寫好的文檔是主動投資的另一個例子。
如果您進行戰略性編程,則將不斷對系統設計進行小幅改進。
權衡:ROI 一開始,戰術性的編程方法將比戰略性方法更快地取得進展。但是,在戰術方法下,復雜性積累得更快,從而降低了生產率。
隨著時間的流逝,戰略方針會帶來更大的進步。注意:此圖僅用于定性說明;我不知道對曲線精確形狀的任何經驗測量。
相反,如果您進行戰術編程,則可以將第一個項目完成的速度提高 10%到 20%,但是隨著時間的推移,復雜性的累積會降低開發速度。不久之后,您的編程速度至少會降低 10–20%。您將很快退回在開始時節省的所有時間,并且在系統的整個生命周期中,與采用策略性方法相比,您的開發速度將更加緩慢。
可持續迭代演化的系統:演進式架構(Evolutionary Architecture)
與傳統的前期、重量級的企業架構設計相比,我們建議采用演進式架構(Evolutionary Architecture)。它提供了企業架構的好處,卻沒有試圖準確預測未來所帶來的問題。
演進式架構不需要猜測組件將如何被重用,而是支持適應性,使用適當的抽象、數據庫遷移、測試套件、持續集成和重構來收獲系統內發生的重用。
盡管我們盡了最大努力,但復雜度仍會隨著時間的推移而增加,但是更簡單的設計使我們能夠在復雜性壓倒性優勢之前構建更大,功能更強大的系統。復雜性的應對永遠不會是一勞永逸,我們需要不斷地推陳出新,是動態、漸進的重塑自己對軟件系統的認識,不斷認識問題和尋找更優解的持續迭代:
互聯網行業的軟件系統,很難一開始就做出完美的設計,通過一個個功能模塊衍生迭代,系統才會逐步成型;對于現存的系統,也很難通過一個大動作,一勞永逸地解決所有問題。系統設計是需要持續投入的工作,通過細節的積累,最終得到一個完善的系統。因此,好的設計是日拱一卒的結果,在日常工作中要重視設計和細節的改進。
- 通過使代碼更簡單和更清晰(Obvious)來消除復雜性。例如: 減少特殊場景的處理,或變量命名一致性都能降低系統復雜性。代碼能夠描述程序的工作流程和結果,卻很難描述開發人員的思路,而注釋和文檔可以。此外,通過注釋和文檔,開發人員在不閱讀實現代碼的情況下,就可以理解程序的功能,注釋間接促成了代碼抽象。好的注釋能夠幫助解決軟件復雜性問題,尤其是認知負擔和不可知問題(Unknown Unknowns)。
- 通過分層或者分模塊來封裝它,對復雜問題的抽象然后分而治之,以便程序員可以在系統上工作而不會立即暴露其所有復雜性。這種方法稱為模塊化設計。在模塊化設計中,軟件系統分為模塊,例如面向對象語言的類。這些模塊被設計為彼此相對獨立,以便程序員可以在一個模塊上工作而不必了解其他模塊的細節。
- 專業化分工和代碼復用,促成了軟件生產率的提升。比如硬件工程師、軟件工程師(底層、應用、不同編程語言)可以在無需了解對方技術背景的情況下進行合作開發;同一領域服務可以支撐不同的上層應用邏輯等等。其背后的思想,無非是通過將系統分成若干個水平層、明確每一層的角色和分工,來降低單個層次的復雜性。同時,每個層次只要給相鄰層提供一致的接口,可以用不同的方法實現,這就為軟件重用提供了支持。分層是解決復雜性問題的重要原則。
- 與分層類似,分模塊是從垂直方向來分解系統。分模塊最常見的應用場景,是如今廣泛流行的微服務。分模塊降低了單模塊的復雜性,但是也會引入新的復雜性,例如模塊與模塊的交互
4. 軟件架構編年史
- 20 世紀 50 年代非結構化編程~1951 – 匯編
- 20 世紀 60 年代結構化編程分層: 用戶界面、業務邏輯數據存儲都在一層。~1958 – Algol
- 20 世紀 70 年代過程式/函數式編程~1970 – Pascal~1972 – C1979 – MVC 模式(Model-View-Controller)
- 20 世紀 80 年代面向對象編程 (但其思想在 20 世紀 60 年代晚期已經第一次提出)分層: 兩層,第一層是用戶界面,第二層是業務邏輯和數據存儲~1980 – C++CORBA – 通用物件請求代理架構(盡管1991 年才推出第一個穩定版,但最早使用可以追溯到 20 世紀 80 年代)~1986 – Erlang~1987 – Perl1987 – PAC 即 HMVC 模式(Hierarchical Model-View-Controller)1988 – LSP(里氏替換原則) (~SOLID)
- 20 世紀 90 年代分層: 三層,第一層是用戶界面,第二層是業務邏輯(以及瀏覽器作為客戶端時的用戶界面展現邏輯),第三層是數據存儲~1991 – 消息總線~1991 – Python/ target=_blank class=infotextkey>Python/ target=_blank class=infotextkey>Python1992 – EBI 架構(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 服務~1997 – ESB – 企業服務總線 (盡管創造該術語的書籍 2004 年才出版,但這個概念早已被使用)
- 21 世紀 00 年代2002 – SRP (~SOLID)2003 – 領域驅動設計2005 – MVVM 模式(Model-View-ViewModel)2005 – 端口和適配器架構即六邊形架構2006 – CQRS 與 ES (命令查詢職責分離與事件溯源)2008 – 洋蔥架構2009 – 微服務.NETflix)
- 21 世紀 10 年代2010 – DCI 架構(Data-Context-Interaction)2012 – 整潔架構2014 – C4 模型
5. 編程哲學:禪與計算機程序設計藝術
美麗勝于丑陋。
顯式優于隱式。
簡單勝于復雜。
復雜勝于復雜。
扁平比嵌套好。
疏勝于密。
可讀性很重要。
特殊情況不足以打破規則。
盡管,實用第一,簡潔第二。
錯誤永遠不應該無聲無息地過去。
除非明確沉默。
面對曖昧,拒絕猜測的誘惑。
應該有一種——最好只有一種——顯而易見的方法來做到這一點。
雖然這種方式一開始可能不明顯,除非你是荷蘭人。
現在總比沒有好。
雖然永遠不會比現在好。
如果實現很難解釋,那就是一個壞主意。
如果實現容易解釋,這可能是一個好主意。
命名空間是一個非常棒的主意——讓我們做更多這樣的事情吧!
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. 架構師
架構師,是一個既能掌控整體全局,又能洞悉局部瓶頸,并依據具體的業務場景,給出解決方案的團隊領導型人物。
軟件系統架構師綜合的知識能力包括9個方面,即:
1、戰略規劃能力。
2、業務流程建模能力。
3、信息數據結構能力。
4、技術架構選擇和實現能力。
5、應用系統架構的解決和實現能力。
6、基礎IT知識及基礎設施、資源調配能力。
7、信息安全技術支持與管理保障能力。
8、IT審計、治理與基本需求分析、獲取能力。
9、面向軟件系統可靠性與系統生命周期的質量保障服務能力。
作為系統架構師,必須成為所在開發團隊的技術路線指導者;具有很強的系統思維的能力;需要從大量互相沖突的系統方法和工具中區分出哪些是有效的,哪些是無效的。架構師應當是一個成熟的、豐富的、有經驗的、有良好教育的、學習快捷、善溝通和決策能力強的人。豐富是指他必須具有業務領域方面的工作知識,知識來源于經驗或者教育。他必須廣泛了解各種技術并精通一種特定技術,至少了解計算機通用技術以便確定那種技術最優,或組織團隊開展技術評估。優秀的架構師能考慮并評估所有可用來解決問題的總體技術方案。需要良好的書面和口頭溝通技巧,一般通過可視化模型和小組討論來溝通指導團隊確保開發人員按照架構建造系統。
具備的能力
(1)技術能力
技術能力,不用置疑肯定是最重要的。技術能力弱的架構不是一個好架構。所以,你需要知道所有主流技術的基本原理、應用場景,及快速解決問題的能力。所以,架構師必須要有見識,所需知識面肯定是要不斷拓展的。你需要清楚在什么樣的場景用什么樣的技術比較合適,并知道可能存在什么樣的風險。來了需求,你腦袋是空的,不知道用什么技術這是最可怕的。
(2)架構能力
這個可以表現為抽象能力、整體規劃能力、及設計能力。你需要照在業務的角度進行系統分解、技術選型、架構搭建,以及規范制定。架構出來了至少可以滿足最近的發展,或者可以很方便對現有架構進行擴容。有人說架構不需要懂業務,我面試過的就有明確表示不做業務架構。當然有方面的架構師,如中間件架構師,運維基礎設施架構師等。但一般的后端架構師都是需要了解業務,不理解業務你如果進行系統分解,服務劃分,及根據不同業務作出不同的架構。技術都是為業務服務的,不站在業務的角度設計架構,那架構就是空談。[1]
(3)溝通能力
這個看起來不是最重要的,其實也非常重要。作為一個優秀的架構師,你需要清楚的知道客戶的需求,需要不斷和需求人員進行溝通,以達到客戶真正的目的。不論是不是架構師,任何一個職場人,提高自己的溝通表達能力無疑是不可或缺的。有一句話怎么說的,領導就喜歡拍馬屁的。做領導的大多不是技術特別牛的,但溝通能力肯定是很好的。