應用的架構是「架構活動(architecting)」這個過程的產物。本節討論「架構活動是什麼」「由誰執行」「何時進行」。

架構視為一連串設計決策#

「架構是一組明確設計決策(design decisions)的合成。」 ——Anton Jason and Jan Bosch,《Software Architecture as a Set of Architectural Design Decisions》

依此觀點,架構活動就是「做這些設計決策」的過程。每個設計決策包含六個元素:

Figure 3.17: An architecture is the composition of design decisions (problem, motivation, cause, candidates, decision, rationale)

  • Problem:要解的問題。
  • Motivation:為什麼這是個問題。
  • Cause:問題的成因。
  • Candidate solutions:可選解法及其權衡(trade-off)。
  • Decision:選定的解法。
  • Rationale:為何選擇此解法,例如以 Architecture Decision Record(ADR)記錄。

被選定的解法會修改架構——新增/刪除/修改元素、關係、設計規則(rule)、限制(constraint),這些規則會進一步約束未來的設計決策。

範例:選擇分層架構,等同於引入了:

  • 元素:web/api、domain、infrastructure 等層。
  • 規則/限制:所有元素必須屬於某一層;一層只能依賴正下方那一層。

把架構視為一連串設計決策有兩個顯著好處:

  • 每個架構元素都能追溯到一個設計決策,意味著「它存在,當且僅當它解決了一個問題」——這是避免過度設計的好原則。
  • 保留設計理由:防止架構演化過程中發生「knowledge vaporization(知識蒸發)」,讓決策背後的理由不會因為時間流逝而消失。

誰來做架構決策#

當然是「人」做決策——但哪些人?開發者?架構師?嵌入團隊的架構師,還是獨立的架構小組?

選擇時要兼顧三件事:

  • 品質(Quality):架構決策必須滿足所有受影響者的需求。
  • 速度(Speed):在流暢交付的時代,決策必須快。
  • 共識(Buy-in):被決策影響的人必須認同這個決策。

Gregor Hohpe 在《Would you like architects with your architecture?》提出四種選項:

  • Benevolent dictator(仁慈獨裁者):獨立於開發團隊的個人或小組做所有架構決策,團隊只負責落實。
  • Architect in the team(嵌入團隊的架構師):架構師是團隊成員,在團隊內部做架構決策。
  • Architecture done by team members(由團隊成員自行架構):每個團隊裡的部分成員兼任架構決策角色。
  • Implicit architecture(隱式架構):沒人有意識地思考架構。

Figure 3.18: The four options for who does architecture — benevolent dictator, architect in the team, architecture done by team members, implicit architecture

兩個壞選項#

完全集中式決策(benevolent dictator) 在某些情況有用(例如團隊陷入決策癱瘓),但有三個重大問題:

  • 決策品質差:架構師脫離開發者真實需求,容易做錯決定。
  • 決策慢:開發團隊得等中央決策。
  • 缺乏共識:強加的決策難以獲得認同。

隱式架構 對非平凡的應用幾乎是災難——每個應用都會有架構,即使沒人刻意設計。沒有設計的應用通常會變成大泥球,開發越走越慢。

兩個好選項:去中心化架構#

把架構決策移到團隊(架構師嵌入團隊,或由團隊成員兼任)有三個好處:

  • 避開瓶頸,團隊能快速做決策。
  • 決策更貼近現實,不脫離程式碼。
  • 團隊自然 buy-in,因為他們參與決策。

Architecture Advice Process(架構建議流程)#

去中心化的挑戰在於:怎麼確保決策資訊充足且跨組織一致? 答案來自 Andrew Harmel-Law《Facilitating Software Architecture》的「架構建議流程」:

任何人(無論是開發團隊成員或外部架構師)只要做到下列一點,就可以做出並公告架構決策:

向所有受影響者與該領域專家徵詢意見,讓他們對候選解法與權衡發表看法。

這個流程有兩面好處:架構師會理解決策對開發團隊的衝擊;開發團隊也會理解更宏觀的脈絡。Chris Richardson 認為這是每個組織都應該採行的實踐

微服務架構的雙層架構決策#

分散式架構(例如微服務)需要在兩個層級做架構決策:

  • 單一服務的架構:由擁有該服務的團隊負責。
  • 整體應用層級:跨服務共通的關注點(例如基礎設施)需要有人從整體視角思考。
    • 小型應用:整體架構可由所有團隊集體負責。
    • 較大型應用:常見做法是設立專門的架構團隊

從 Team Topologies 的角度看,這個架構團隊結合了 platform team 與 enabling team 的角色:

  • 平台角色:提供承載架構的內部平台,降低開發團隊的認知負荷。
  • 賦能角色:提供架構諮詢,協助開發團隊解決架構難題。

何時做架構#

Gall’s Law(出自 John Gall《Systemantics: How Systems Really Work and How They Fail》):

「一個有效運作的複雜系統,無一例外,都是從一個有效運作的簡單系統演化而來。從零開始設計的複雜系統永遠跑不起來,也無法被修補成可以跑起來。你必須從一個能跑的簡單系統重新開始。」

實作上的指引:

  • 從最簡單能運作的架構開始,隨著應用成長再演化架構。
  • 對應「架構是一連串設計決策」的觀點:只為「現在真的需要解決的問題」做設計決策;隨著新問題出現,再做相應決策。

「只解決你真的有的問題」聚焦於簡潔,能避免在還沒有第一位客戶之前就過度設計。

例外:有具體證據(而不是一廂情願)顯示未來會出現某類問題時,提前做相應的設計決策也是合理的。例如:使用者量正快速成長,你預估 N 個月後負載會超過現有架構承受度,提前提升 scalability 就是有依據的決策。

章節重點摘要#

  • 架構是一組「需要用來推理應用」的結構,由元素與關係組成。
  • 架構之所以重要,是因為它讓應用能滿足品質屬性。
  • 兩大類品質屬性:開發期(modifiability、testability、deployability)與執行期(availability、performance、security)。
  • 架構是多維度的,包含四個靜態視角(domain、component、deployment、build)與一個動態視角(scenarios)。
  • 架構風格是對元素與關係的限制集合;layered、hexagonal、monolithic、microservice 都是架構風格的例子。
  • 架構活動是做架構決策的過程,主要應由開發團隊負責;微服務架構在跨服務面向上,通常需要設立專門的架構團隊處理跨切面問題(如基礎設施)。
  • 任何架構決策者都應徵詢受影響者與領域專家的意見
  • 建構最簡單能運作的架構,並隨具體需求演化。