架構特性與權衡#

複雜度管理告訴我們架構是為了解決複雜度,但「複雜度」本身過於籠統。要把它落到可設計、可驗證的層面,需要一套更精確的語言:架構特性(Architecture Characteristics),也就是業界常說的「非功能需求」或「品質屬性(Quality Attributes)」。本章釐清這些名詞的差異,說明如何辨識真正該關注的特性,以及為什麼這些特性之間必然要取捨

三個容易混淆的名詞#

名詞觀點說明
功能需求(Functional Requirement)業務/使用者系統「做什麼」,例如「使用者可以下單」
非功能需求(Non-functional)反向定義不是功能的需求,名稱消極,難以驅動設計
品質屬性(Quality Attribute)品保/驗收對系統「品質」的衡量,例如可用性 99.95%
架構特性(Architecture Characteristic)架構師「會影響結構決策」的非功能面向,是架構師主動要設計的對象

這三者大量重疊,但「架構特性」這個說法最貼近架構師的工作:它強調的是那些一旦選定就會塑造系統結構的面向。並非所有非功能需求都是架構特性——有些可以靠後期調校解決,不影響結構。

把焦點從「非功能需求」轉成「架構特性」,是把消極的清單(「不要慢、不要當機」)翻譯成積極的設計目標(「為高吞吐而設計」),這樣才能驅動結構決策。

三判準:什麼才算架構特性#

一個面向要被列為架構特性,需同時滿足三個條件。任一不滿足,就不該佔用架構師的設計預算。

判準問題反例
非領域它是否與具體業務功能無關?「支援信用卡付款」是功能,不是架構特性
影響結構滿足它是否需要特定的結構設計?「按鈕要圓角」不影響結構,不是架構特性
對成功關鍵它對系統成敗是否真的重要?過度設計常源於把「可有可無」誤當「關鍵」

第三個判準最常被忽略。架構師傾向把所有特性都拉到「重要」,導致過度設計。請參考簡單原則:能不列就不列,每多一個特性都會增加結構複雜度。

架構特性的三大分類#

把架構特性歸類,有助於在需求訪談時系統性地「掃描」,避免遺漏。

操作型(Operational)#

與系統運行時的行為有關,多半可量化、可監控。

特性衡量問題
可用性(Availability)系統需要多高的正常運行時間?
效能(Performance)回應延遲、吞吐量的目標為何?
可恢復性(Recoverability)災難後多久要恢復(RTO/RPO)?
可擴展性(Scalability)負載增加時系統如何成長?

這些與高效能高可用可擴展性章節高度相關。

結構型(Structural)#

與程式碼的內部品質與組織方式有關,多半難以量化。

特性衡量問題
可維護性(Maintainability)修改一個功能要動多少地方?
可測試性(Testability)能否容易地撰寫自動化測試?
可部署性(Deployability)發布一次的成本與風險有多大?
可擴充性(Extensibility)加新功能是「插入」還是「動手術」?

跨領域(Cross-cutting)#

橫跨整個系統、不易歸入前兩類,卻往往攸關存亡。

特性衡量問題
安全性(Security)認證、授權、加密的需求為何?
法規遵循(Compliance)是否受 GDPR、金融法規約束?
隱私(Privacy)個資如何蒐集、保存、刪除?
可用性/無障礙(Accessibility)是否需符合無障礙標準?

隱式特性最易漏#

架構特性可分為**顯式(Explicit)隱式(Implicit)**兩種:

  • 顯式特性:寫在需求文件裡,業主明確提出(例如「尖峰每秒一萬筆交易」)。
  • 隱式特性:沒人寫下來,卻被預設一定要有(例如安全性、資料一致性、合理的可用性)。

災難多半來自隱式特性。沒人會在需求裡寫「請不要洩漏使用者密碼」,但漏掉它後果嚴重。架構師的價值之一,正是主動把隱式特性挖出來、攤在桌面上討論。

挖掘隱式特性的提問清單:

  • 這個產業有沒有監管或合規要求?
  • 競品都具備、使用者預期一定有的非功能面向是什麼?
  • 哪些「不出事就沒人提,一出事就上新聞」的面向(安全、隱私、資料完整)?

特性間必然取捨:不可全要#

架構特性之間存在相互拉扯,幾乎不可能同時最大化。試圖「全都要」會得到一個處處平庸的系統。

flowchart LR
    P[效能] -.衝突.- S[可擴展性]
    S -.衝突.- C[一致性]
    SEC[安全性] -.拖慢.- P
    SIMP[簡單性] -.犧牲.- EXT[可擴充性]

    style P fill:#e3f2fd
    style S fill:#e8f5e9
    style C fill:#fff3e0
    style SEC fill:#ffebee
    style SIMP fill:#f3e5f5
    style EXT fill:#ede7f6

典型的取捨關係:

取捨對拉扯關係
效能 ↔️ 安全性每一層加密、驗章都增加延遲
可擴展性 ↔️ 一致性分散式擴展常被迫放寬一致性(見分散式系統的 CAP)
可擴充性 ↔️ 簡單性為了「以後好擴充」而抽象,當下就變複雜
可用性 ↔️ 一致性網路分割時,要嘛保可用、要嘛保一致
上市時間 ↔️ 任何品質特性趕工幾乎一定犧牲某項架構特性

架構師的工作不是「達成所有特性」,而是在衝突的特性間做出明確、可被追溯的取捨。把取捨的理由記錄下來,正是 ADR 存在的理由。

設計時建議只挑出 3 ~ 7 個 真正關鍵的「驅動特性」,其餘列為「次要」,明確告知會被犧牲。

範例:把模糊需求翻譯成架構特性

業主原話:「我們要做一個很穩、很快、以後好加功能的電商後台。」

翻譯成可設計的架構特性與取捨:

業主說法架構特性量化目標取捨決定
「很穩」可用性99.9%(年停機 8.8h)不追求 99.99%,避免異地多活成本
「很快」效能P99 < 300ms接受最終一致以換取讀取效能
「好加功能」可擴充性/可維護性新功能不改核心接受初期多一層抽象的複雜度
(隱式)安全性通過支付資安稽核顯式列出,列為關鍵特性

關鍵:把「很穩、很快」這種無法驗收的形容詞,逼成可量測、可取捨的目標。

本章小結#

主題核心觀點
名詞辨析架構特性 = 會影響結構、攸關成敗的非功能面向
三判準非領域、影響結構、對成功關鍵——三者缺一不可
三分類操作型、結構型、跨領域,用於系統性掃描需求
隱式特性沒寫下來的(安全、合規)最易漏,也最致命
必然取捨特性彼此衝突,只挑 3 ~ 7 個關鍵,其餘明確犧牲

每次架構評審,先問三題:我們在優化哪些特性?我們明確放棄了哪些特性?這些取捨記錄在哪?答不出來,代表特性還沒被想清楚。