軟件架構被高估,清晰簡單的設計被低估

軟件架構最佳實踐、企業架構模式以及系統描述的正式方法都是非常重要且實用的工具,總會有合適的場景讓它們發揮作用。但在設計系統時,請從簡單始、以簡單終,儘可能避免一切會無謂提高複雜度的架構與正式工具。

我的職責是設計和構建大型系統。我參與重寫了Uber的分佈式支付系統,設計並交付了Skype on Xbox One,開源了Uber的移動架構框架RIBs。所有這些系統都進行了徹底的設計,經過多次迭代和大量討論。然後,這些設計被記錄到設計文檔中,在我們開始構建之前分發出去,從而獲得更多的反饋。

所有這些系統的規模都很大:有數百名開發人員在構建它們——或者以它們爲基礎進行構建——並且它們支撐着每天數百萬人使用的系統。它們不僅僅是綠地項目。重寫的支付系統就是用於替換兩個已有的支付系統,有幾十個系統、數十個團隊在使用它們,但所有這些都沒有對業務產生任何影響。重寫Uber App是一個由數百名工程師同時參與的項目,他們將現有的功能移植到一個新的架構中。

讓我先說些可能會讓你覺得吃驚的事。首先,這些設計都沒有使用任何標準的軟件架構規劃工具。我們沒有使用UML,沒有使用4+1模型,沒有使用ADR,也沒有使用C4依賴關係圖。我們創建了大量的圖表,但是沒有遵循任何嚴格的規則。只是使用了普通的方框和箭頭,類似於這個描述信息流的圖或這個概括類結構和組件之間關係的圖。同一個設計文檔中的兩個圖經常會有不同的佈局,並且經常由不同的工程師添加和修改。

其次,負責設計的團隊中沒有架構師。沒有IT架構師企業架構師。沒錯,Uber和Skype/微軟都沒有袖手旁觀的軟件架構師職位。級別較高的工程師和普通工程師一樣,仍然需要定期編寫代碼。對於所有的項目,我們都有經驗豐富的工程師參與。然而,沒有人專門負責架構或設計。經驗豐富的開發人員確實推動了設計過程。不過,即使是最初級的成員也在設計過程中進行了輸入,他們經常會挑戰決策,並提供其他可供討論的替代方案。

第三,我們實際上沒有引入常見的架構模式以及常見的軟件架構文獻中引用的其他術語,比如Martin Fowler的架構指南。沒有提到微服務、無服務器架構、應用程序邊界、事件驅動架構等。其中一些在頭腦風暴時確實提到過,但是,沒有必要在設計文檔中引用它們。

科技公司和初創企業的軟件設計

那麼,我們是如何完成任務的呢?爲什麼我們不遵循著名的軟件架構方法所建議的方法呢?

我曾與其他科技公司(Facebook、亞馬遜、Netflix、谷歌)以及規模較小的初創公司的同行們討論過這個問題。大多數團隊和項目無論大小,都採用類似的設計和實現方法:

  1. 從業務問題入手。我們要解決什麼問題?我們要設法構建什麼產品?爲什麼?我們如何度量成功?

  2. 通過頭腦風暴找出方法。與團隊一起,通過多次會議,找出可行的解決方案。務必保證這些頭腦風暴的規模要小。從高層開始,逐步下降到較低的層次上。

  3. 藉助白板說明方法。把團隊聚集在一起,讓一個人繪製出團隊趨向於採用的方法。你應該能夠在白板上清楚地解釋你的系統/應用程序的架構,從高層開始,根據需要逐步深入。如果你覺得解釋有困難或者不夠清楚,就需要在細節上做更多的工作。

  4. 根據你在白板上的解釋,使用簡潔的文檔和圖表詳細描述設計。儘量少用術語:要讓初級工程師也明白它的意思。用清晰易懂的語言寫下來。在Uber,我們使用一個帶有基本模板的類似RFC的文檔。

  5. 討論權衡可選方案。良好的軟件設計和架構重點在於做出正確的權衡。設計選擇本身沒有好壞之分:它完全取決於上下文和目標。架構是否要劃分爲不同的微服務?說明一下爲什麼你決定不使用單體架構,它可能有其他一些好處,比如部署更簡單更快速。你是否選擇使用新功能擴展服務或模塊?權衡構建單個服務或模塊的選項,以及這種方法的優缺點。

  6. 在團隊/組織內分發設計文檔並獲得反饋。在Uber,我們曾經把所有的軟件設計文檔發給所有的工程師,直到我們的工程師人數達到大約2000名。現在我們的人數更多了,我們仍然廣泛地分發設計文檔,但是我們已經開始更多地平衡信噪比。我們鼓勵人們提出問題並提供替代方案。要根據實際情況設定合理的反饋時間限制,討論反饋意見,並根據需要加以採納。簡單明瞭的反饋可以現場快速處理,而更復雜的反饋現場處理也可能會更快。

爲什麼我們的方法與軟件架構文獻中經常提到的方法不同?實際上,我們的方法與大多數架構指南在原則上並沒有太大的不同。幾乎所有的指南都建議從業務問題開始,概述解決方案並進行權衡:我們也是這樣做的。我們沒有使用許多架構師或架構書籍提倡的更復雜的工具。我們使用最直接的工具(如谷歌Docs或Office365)儘可能簡單地記錄設計。

我認爲,在這些公司中,我們的方法的主要區別在於工程文化。自主性高和層級少是科技公司和初創企業的共同特點:對於更傳統的公司來說,有時並非如此。這也是爲什麼這些地方使用更嚴格的規則進行更多的“基於常識的設計”,而不是流程驅動的設計。

我知道一些銀行和汽車公司,它們的開發人員在沒有得到高層架構師的批准之前,不願做出任何架構決策,而這些架構師負責管理多個團隊。這會是一個比較緩慢的過程,架構師可能會被許多請求淹沒。因此,這些架構師創建了更正式的文檔,希望通過更多地使用常見文獻中介紹的工具使系統更清晰。這些文檔還強化了自上向下的方法,因爲對於非架構師工程師來說,質疑或挑戰已經用正式方法記錄下來的、他們不是很熟悉的決策更令人生畏。所以他們通常不會這麼做。公平地說,這些公司常常希望使開發人員成爲更容易替換的資源,以便他們可以在短時間內重新分配人員從事不同的項目。不同的工具在不同的環境中可以更好地發揮作用,這應該不足爲奇。

簡單、無術語的軟件設計勝過架構模式

系統設計的目標應該是簡單。系統越簡單,理解起來就越容易,就越容易發現問題,實現起來也就越簡單。使用的描述語言越清晰,設計就越容易理解。避免使用團隊中每個成員都不理解的術語:即時是經驗最少的人也應該能夠同樣清楚地理解設計。

簡潔的設計類似於簡潔的代碼:易於閱讀和理解。有許多好方法可以編寫出簡潔的代碼。然而,你很少聽到有人一開始就建議將設計模式應用到你的代碼中。簡潔的代碼從單一職責、清晰的命名和易於理解的約定開始。這些原則同樣適用於簡潔的架構。

那麼,架構模式的作用是什麼?我認爲它們與編碼設計模式同樣有用。它們可以爲你提供關於如何改進代碼或架構的思路。對於編碼模式,當我看到一個單例模式時,我就會注意到它;當我看到一個類僅充當執行調用的外觀時,我就會揚起眉毛,深入研究。但我還沒有想到“這需要一個抽象工廠模式”。事實上,在處理了大量依賴注入之後,我花了很多時間來理解這個模式的作用,並且終於在某個時刻恍然大悟——這實際上是這個模式非常常見並且非常有用的少數幾個領域之一。我還得承認,雖然我花了很多時間閱讀和理解GoF設計模式,但與我從其他工程師那裏得到的代碼反饋相比,它們對於我成爲一名更好的程序員的影響要小得多。

類似地,瞭解常見的架構模式是一件好事:它有助於縮短與他人討論的時間,他們和你一樣理解那些模式。但是架構模式並不是我們的目標,它們也不能代替更簡單的系統設計。在設計系統時,你可能會無意中應用了一個衆所周知的模式:這是一件好事。後續你要參照這個方法就更容易了。但是,你最不希望看到的是使用一個或多個架構模式,把它當成一把錘子,爲了用它而到處找釘子。

工程師們觀察到,人們在某些情況下會做出類似的設計選擇,並且這些選擇的實現方式也非常類似,於是,就誕生了架構模式。然後,這些選擇被命名、記錄,並被廣泛地討論。架構模式是在制定解決方案後出現的工具,目的是簡化工程師的工作。作爲一名工程師,你的目標應該更多地是制定解決方案並從中學習,而不是選擇一個閃亮的架構模式,希望它能解決你的問題。

如何更好地設計系統?

我聽到許多人詢問如何更好地架構和設計系統。一些有經驗的人會推薦你閱讀架構模式和軟件架構方面的書籍。我肯定也推薦閱讀——尤其是書籍,因爲它們比一篇短文更有深度——但我還是有一些建議,這些建議比單純的閱讀更具實踐性。

  • 拉過一名同事,在白板上寫下你的設計方法。寫出你在做什麼,爲什麼要這麼做。確保他們能理解。當他們能理解的時候,徵求他們的意見。

  • 將你的設計詳細記錄在一個簡單的文檔中,並與你的團隊分享,尋求反饋。不管你正在處理的事情多麼簡單或複雜,可能是較小的重構,也可能是大型項目,總結一下。採用一種對你而言有意義的方式,一種別人能理解的方式。爲了幫你尋找靈感,我在這裏分享了我在Uber看到的做法。與團隊共享時採用一種可以評論的格式,如谷歌文檔、Office365等。讓人們添加他們的想法和問題。

  • 設計兩種方案,並進行對比。大多數人在設計架構時都只採用一種方法,就是突然出現在他們腦海中的方法。然而,架構並不是非黑即白的。提出第二個同樣可行的設計。對比兩者,解釋爲什麼一個比另一個更好。簡要列出第二種設計作爲備選方案,並說明爲什麼決定不用它。

  • 要清楚你所做的權衡,爲什麼要做這些權衡,以及你優化了哪些東西。要清楚存在的約束,並且必須考慮到這些約束。

  • 評審別人的設計,並取長補短做到更好。假設你們有這樣一種文化,人們通過白板、會議或文檔來分享他們的設計,那麼你就能從評審意見中瞭解到更多的東西。在評審過程中,大多數人只是試着接受一些東西,成爲單向的觀察者。我們不能侷限於此。相反,對於不清楚的部分要通過提問來弄清楚。詢問他們考慮過的其他選項。問他們做了哪些權衡,假設了哪些約束條件。要唱反調,提出另一個可能更簡單的選項——即使不是更好的選項——問問他們對你的建議有何看法。即使你沒有像設計展示者那樣思考得那麼深入,你仍然可以帶來很多有價值的東西並學到更多的東西。

最好的軟件設計是簡單易懂的設計。下次啓動一個新項目時,不要想着“我將如何構建這個系統,我應該使用哪些經過實戰檢驗的模式,以及我應該使用哪些形式化的方法來記錄它?”,而是要想一想“我怎麼才能想出一種任何人都很容易理解的、最簡單的設計?”

原文鏈接:Software Architecture is Overrated, Clear and Simple Design is Underrated

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章