如何成為更好的軟體架構師?這篇3.8K star的文章值得一看
選自GitHub
作者:Justin Miller
機器之心編譯
參與:王子嘉、魔王
幾天前,高級架構師 Justin Miller 在 GitHub 上創建項目,介紹自己關於「如何成為更好的軟體架構師」的想法。該項目發布一天即獲得 1.4K star,現在已有 3.8K star 量。
幾年前有人問我:「你是怎麼成為一名軟體架構師的?」我們就此探討了必備技能、經驗,以及儲備相關知識所需的時間和精力。除此之外,我也回顧了自己走過的路、使用或嘗試過的技術,以及我從那些五花八門的工作中學到的東西。
架構師技術路線圖。
軟體架構師是什麼?
在進行深層次的探討之前,我們先來看兩個定義:
軟體架構師是指那些制定高級設計決策,並確定技術標準(包括軟體編程標準、工具和平台)的軟體專家。這之中的首席專家就是總架構師。(來源:Wikipedia: Software Architect)
軟體架構是系統的基本組織構成,這種組織主要體現在其組件、組件之間的關係、組件與環境之間的關係,以及決定系統設計與演化的原則。(來源:Wikipedia: Software Architecture)
架構的「層級」
架構主要可以抽象成以下幾個「層級」。不同層級所需的技能也不同。儘管對層級的分類有很多種標準,但是我最喜歡把架構分成 3 個層級:
應用級:最低層級的架構。只關注單一的應用。層級低,但是很詳細。這方面的交流一般是在一個開發團隊內展開;
解決方案級:架構的中間層。關注一或多個滿足業務需求的應用(也就是商業方案)。這之中有些設計是高層次的,但大部分還是低層次的設計。這種層級架構的交流就開始涉及多個團隊了;
企業級:架構的最高層級。關注多個方案。這種架構的設計層次高且抽象,因此也需要方案級和應用級的架構師對此進行細化。這種層次的架構就需要多個組織進行溝通了。如果你想了解更多,可以參閱這個鏈接:https://github.com/justinamiller/EnterpriseArchitecture。
有時候,架構師也被看做不同工作組之間的粘合劑。以下是三個例子:
橫向:在業務部和開發人員或是不同的開發團隊之間架起溝通的橋樑;
縱向:在管理者和開發人員之間架起橋樑;
技術:將不同的技術或應用整合在一起。
軟體架構師的日常
要了解架構師的必備技能,我們得先知道架構師主要做什麼。我認為架構師最重要的活動包括:
定義和確定所需的開發技術與平台;
定義開發標準,如編程標準、工具、審核流程、測試方法等;
對確定和理解業務需求提供支持;
設計系統並根據需求做出決策;
對架構定義、設計和決策進行討論記錄;
檢查並審核架構與代碼,比如檢查前期確定的模式與編程標準是否被正確實施;
與其他部門和架構師合作;
對開發人員的引導及諮詢;
將高級設計細化,並轉化為較低級的設計。
注意:架構設計是一項持續性的工作,尤其是在敏捷軟體開發過程中。因此,我們會一遍又一遍地重複這些工作。
軟體架構師必備技能
為了完成上面說的那些工作,架構師需要具備一些特定的技能。從我的個人經驗、相關書籍和討論中,我們可以將其總結為以下 10 項技能:設計、決策、簡化、編程、記錄、溝通、估算、平衡、諮詢、市場。
接下來我將逐一介紹這些技能。
設計
首先最重要也最難回答的問題就是「什麼是好的設計」。我將從理論和實踐兩個層面進行闡述。就我的經驗來說,兩者兼備才是最好的。那我們先說一下理論層面吧:
了解基本的設計模式:模式是架構師開發可維護系統所需的最重要工具之一。基於這些模式,你可以把一些已經在其他問題上奏效的方案遷移到一些模式相同的新問題上。「Gang of Four」(GoF) 所著《Design Patterns: Elements of Reusable Object-Oriented Software》是所有從事軟體開發的人的必讀書。儘管這些模式發佈於 20 多年前,它們仍是現代軟體體系結構的基礎。例如書中的模型-視圖-控制器(Model-View-Controller,MVC)模式就被應用於許多領域,它同時也是一些新模式(如 MVVM)的基礎;
再挖深一點,研究一下模式與反模式(anti-pattern):如果你對 GoF 所寫的模式具備全面的了解,那麼你就可以學習更多的軟體設計模式了,或者深挖你感興趣的領域。在應用集成領域,我最喜歡的一本書是 Gregor Hohpe 編寫的《企業集成模式》。當兩個應用需要交換數據時,無論是來自一些遺留系統的老式文件交換還是現代微服務體系結構,這本書的內容都適用;
了解質量度量:定義架構還不算完,還要解釋為什麼要定義、應用並控制這些準則和編程標準。這樣做是因為需要控制質量,滿足一些非功能需求。我們想要的是一個可維護、可靠、可適應、安全、可測試、可擴展、可用的系統。而實現所有這些要求的方法就是有一個好的架構設計方法。你可以在維基百科上了解更多關於質量度量的信息。理論很重要,但是如果你不想成為一名活在象牙塔里的架構師,實踐也同樣重要,甚至更加重要;
嘗試並理解不同的技術棧:我認為這是你成為更好架構師之路上最重要的一步。嘗試新的技術棧,並了解其發展歷程。這些不同的技術具有不同的設計理念和模式。只瀏覽 PPT 學不到太多東西,你需要自己去嘗試並感受這項技術的喜與悲。架構師不僅要有廣博的知識面,還要在一些領域有深厚的積累。重點不在於掌握所有的技術棧,而是對你所在領域最重要的技術有堅實的理解。你還可以嘗試一些領域外的技術,例如,如果你對 SAP R/3 有很深的了解,你應該嘗試一下 JavaScript,反之亦然。儘管如此,雙方都會對 SAP S/4 Hana 的最新進展感到驚訝。例如,你可以自己嘗試並免費參加 openSAP 的課程。保持好奇心,多嘗試新事物,也可以嘗試一些幾年前不喜歡的東西;
分析和理解應用模式:查看任意當前框架(如 Angular)。你可以在實踐中學習到很多模式(如 Observables),你還應該試著理解它是如何在框架中應用的,為什麼要這樣做。如果你是真正的專業人士,你還需要更深入地研究代碼並了解它是如何實現的;
保持好奇心,關注用戶群。
決策
架構師需要制定決策,指引項目甚至整個公司的正確方向。
分清主次:不要在不重要的決策和工作上浪費時間,要學會分清主次。就我個人來說,我比較喜歡通過以下兩個特徵來判斷一件事是否重要:
a. 概念完整性:如果你一開始決定了一個理念,堅持下去,即使有時候用不同的方法做會更好。這樣整體概念就更清晰明確,提升了可理解性,也簡化了維護過程。
b. 一致性:例如,如果你定義並應用了命名約定,那麼它不是關於大寫或小寫的,而是以相同的方式應用於所有地方。
優先順序:有些決定非常關鍵,如果沒有及早採取合適的解決方案,很有可能給日後造成無法解決的問題。這對維護人員來說來說是一場噩夢,或者更糟的,開發人員在這個決策制定之前無法繼續工作。在這種情況下,先做一個「糟糕」的決定甚至比沒有決定更好。但是在這種情況發生之前,你要知道哪些決定是應該被優先處理的。有很多方法可以做到這一點。我建議先看看加權最短作業優先(WSJF)模型,它在敏捷軟體開發中被廣泛使用。尤其是時間臨界和風險降低,對這二者的度量是評估架構決策優先順序的關鍵;
認清自己的能力:不要在能力範圍之外的事情上做決定。這很重要,因為如果不加以考慮,它可能會嚴重破壞你作為架構師的地位。為了避免這種情況,你應該和同事明確自己的職責和角色。如果有不止一個架構師,那麼你應當只負責當前負責的架構層級。作為一個較低層級的架構師,你應該為更高層級的架構提出建議,而不是做出決策。此外,我建議你經常和同事一起檢查重要的決定;
評估多種選擇:在做決定時,總是要列出多個選項。在我參與的大多數案例中,都有不止一個可能的(優秀)選擇。不好的選擇主要有這兩個特點:(1)看起來你沒有完成好自己的工作;(2)有礙於作出正確的決定。定義度量後,你就可以根據事實(如許可證成本或成熟度)來比較各種選擇,而不是通過直覺。這通常會讓你做出更好、更可持續的決策。此外,將該決策推廣到其他部門也會更容易。但是如果你沒有正確評估選項,在最終討論時你可能會失去一個重要的論據。
簡化
時刻記住奧卡姆剃刀原則,也就是簡單即正義。我對這個原則的理解是這樣的:如果你的解決方案是在做了很多假設的基礎上提出來的,那麼你的方案很可能是錯的,也很可能會變得極其複雜。這個時候你就應該減少(簡化)一些假設,以獲得更好的解決方案。
多方位觀察解決方案:為了簡化解決方案,經常需要你調整對解決方案的觀察角度。比如,你可以嘗試通過自頂向下和自底向上的思考來獲取解決方案。如果你有一個數據流或流程,那麼首先考慮從左到右,然後再考慮從右到左。在簡化過程中詢問自己:「在完美的世界裡,你的解決方案需要做什麼修正嗎?」,或者「某公司/某人會怎麼做?」。這兩個問題都可以幫助你按照奧卡姆剃刀原則來簡化假設;
退一步:經過激烈而漫長的討論後,常常會得到一些極其複雜的方案。永遠不要把它們當做最終的結果。「退一步」的意思就是:再次從宏觀角度看一下這個問題,當下的方案還說的通嗎?然後再在抽象層面對方案進行重構。有時候暫停討論第二天再繼續是個不錯的選擇。至少對於我來說,我的大腦需要一些時間來處理信息,想出更好、更優雅和更簡單的解決方案;
分而治之:把大問題分解成更小的問題,然後分別解決小問題,並驗證這些小方案是否匹配。最後再退一步來看一下總體情況;
重構並非壞事:如果找不到更好的解決方案,那麼修正一個複雜的解決方案也是不錯的選擇。如果某個解決方案問題很多,你可以稍後重新思考該方案,再將想到的新東西應用到該方案中。重構並非壞事,但是在你開始重構之前,請記住:(1)準備好足夠的自動化測試,以確保系統的正常功能;(2)獲得利益相關者的支持。要了解更多關於重構的知識,我建議閱讀 Martin Fowler 寫的《Refactoring. Improving the Design of Existing Code》。
編程
即使作為企業級架構師(最抽象的架構層級),你仍然應該了解開發人員的日常工作。如果你不了解開發如何完成的,那你可能會面臨兩個主要問題:
開發人員不接受你的說法;
你不了解開發人員的挑戰和需求。
開展副項目:做副項目的目的是嘗試新技術和工具,從而發現目前和未來的開發方式。經驗是觀察、情感和假設的結合 (《Experience and Knowledge Management in Software Engineering》,Kurt Schneider 著)。閱讀教程或對利弊的介紹當然好,但這只是「書本知識」。只有當你自己嘗試時,你才能體驗到開發人員的情緒,才能對事情好壞背後的原因做出假設。使用一種技術的時間越長,你做出的假設就會越好。這會幫助你在日常工作中做出更好的決定。我剛開始編程時,並沒有代碼補全功能,只有一些可以加速開發的實用程序庫。顯然,把那時候的背景知識用在今天,我會做出錯誤的決定。現在我們有大量的編程語言、框架、工具、流程和實踐。只有當你有經驗,對主要趨勢有粗略的了解時,你才能參與到討論中來,並將開發引向正確的方向;
只嘗試需要嘗試的事情:你不可能嘗試所有的事情,這根本是不可能的。你需要一個更結構化的方法。我最近發現了一個資源:ThoughtWorks 的技術雷達,他們將技術、工具、平台、語言和框架分為四類:採納、試驗、評估和暫緩。採納表示「強烈建議業界採用這些技術」,試驗表示「企業應當在風險可控的前提下在項目中嘗試應用此項技術」,評估表示「它對企業的影響還需探索」,暫緩表示「謹慎行事」。有了這種分類方法,我們更容易獲得新事物的概況,並更好地評估下一步要探索的趨勢。
記錄
架構文檔有時很重要,有時卻不那麼重要。例如,架構決策或代碼指南是重要文檔。在開始編程之前,通常需要初始文檔,並且對此不斷細化。因為代碼也可以作為文檔(如 UML 類圖),所以有些文檔可以自動生成。
代碼整潔:好的代碼本身就是最好的文檔。好的架構師應該擁有辨別好壞代碼的能力。Robert C. Martin 寫的《Clean Code》就是這方面很好的學習資料。
在可能的情況下生成文檔:系統變化很快,因此文檔很難及時更新。無論是 API 還是以 CMDB 形式出現的系統環境:底層信息的變化往往太快,因此無法手動更新相應的文檔。例如:如果你的 API 是模型驅動的,你就可以根據定義文件自動生成文檔,或者直接從源代碼生成文檔。有很多工具可以幫你完成這項工作,我認為 Swagger 和 RAML 是很好的起點。
儘可能多記必需的東西,內容儘可能少:不管你需要記錄什麼(如決策文件),試著一次只關注一件事,只記錄這件事的必要信息。豐富的文檔很難閱讀和理解,附加信息應保存在附錄中。特別是決策文件,更重要的是要講一個有說服力的故事,而不是拋出大量的論據。此外,這還能為你和你的同事節省大量時間,因為你們必須閱讀這些文檔。看看你過去做過的一些文檔(源代碼、模型、決策文件等),然後問自己以下問題:「用於理解該文件的所有必要信息都包括在內了嗎?」、「哪些信息是真正需要的,哪些可以省略?」、「文檔有紅線嗎?」
更多地了解架構框架:這一點也適用於所有其他「技術」類建議。我之所以把它放在這裡,是因為像 TOGAF 或 Zachmann 這樣的框架提供了「工具」,這些工具在文檔站點上很重要,儘管它們的附加價值並不局限於文檔。深入了解此類框架將教會你更系統地處理架構。
參考鏈接:https://github.com/justinamiller/SoftwareArchitect
本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。
------------------------------------------------
※AI每日精選:中科院發布編程語言木蘭;歐盟擬公共場所禁用人臉識別
※八大亮點,重視產業力量,第三屆機器之心人工智慧年度評選火熱徵集中