衡量架構特性#

架構特性的定義往往含糊不清,要有效管理架構,首先必須建立客觀的衡量標準。本章從三個面向探討如何衡量架構特性:operational measures、structural measures 與 process measures。

Operational Measures(運營面衡量)#

許多架構特性具有明確的運營面指標,例如 performance(效能)和 scalability(可擴展性)。然而,即使是看似簡單的指標也需要深入思考:

  • 團隊需要為效能指標設定具體的統計模型,而非僅依賴任意數字
  • 前瞻性的組織會設定 K-weight budgets,限制頁面下載的最大位元組數
  • 現代指標如 first contentful paintfirst CPU idle 能更精確反映使用者體驗
  • 高階團隊基於統計分析建立定義,當實際指標偏離預測模型時觸發警報

效能指標並非只是設定一個硬性數字,而應基於統計分析,持續監控並與預測模型比較。

Structural Measures(結構面衡量)#

內部結構特性(如 modularity)的衡量不如效能直觀,但仍有可用的指標工具。

Cyclomatic Complexity (CC)(循環複雜度)是最重要的結構指標之一:

  • 由 Thomas McCabe 於 1976 年提出,用於衡量程式碼的複雜度
  • 計算方式基於圖論,公式為 CC = E - N + 2(E = edges, N = nodes)
  • 若函式無條件判斷,CC = 1;每增加一個條件分支,CC 增加
  • 業界建議 CC 值低於 10 為可接受,低於 5 為理想
  • CC 超過 50 表示程式碼品質極差,再多的 code coverage 也無法挽救

Figure 6.1: Cyclomatic Complexity for the decision function

CC 的合理閾值取決於問題領域的複雜度。關鍵問題是:函式複雜是因為問題本身,還是因為程式碼組織不良?

工程實踐如 TDD(Test-Driven Development)有助於產生低 CC 的方法——因為開發者傾向撰寫小而聚焦的測試,進而產出結構良好、高內聚的程式碼。

Process Measures(流程面衡量)#

部分架構特性與軟體開發流程交叉,例如 agility(敏捷性)是一個複合特性,可分解為:

  • Testability(可測試性):透過 code coverage 工具衡量測試完整度
  • Deployability(可部署性):衡量成功/失敗部署比例、部署耗時、部署引發的問題數等

流程也可能反過來影響架構結構。例如,若部署便利性和可測試性是高優先級,架構師會更強調良好的模組化和隔離性。


Governance 與 Fitness Functions#

治理架構特性#

Governance(治理)源自希臘語 kubernan(引導),是架構師的重要職責。架構治理涵蓋軟體開發過程中架構師希望施加影響的所有面向。

核心問題:當架構師定義了架構特性並排定優先順序後,如何確保開發者尊重這些優先順序?

  • Modularity(模組化)是「重要但不緊急」的典型例子
  • 在專案壓力下,緊急事項往往壓過重要事項
  • 因此架構師需要一套治理機制

Fitness Functions(適應度函數)#

Architecture fitness function 的定義:

任何提供架構特性或其組合之客觀完整性評估的機制。

Fitness function 不是一個新框架,而是對現有工具的新視角。其驗證機制與架構特性本身一樣多樣,包括:

  • Metrics(指標)
  • Monitors(監控)
  • Unit tests(單元測試)
  • Chaos engineering(混沌工程)

Fitness Function 實例#

偵測循環依賴(Cyclic Dependencies):

  • 元件之間的循環依賴會嚴重破壞模組化
  • 使用 JDepend 等工具撰寫測試,將其整合到 CI pipeline 中
  • 自動化偵測能防止開發者無意間引入循環依賴

Figure 6.3: Cyclic dependencies between components

Distance from the Main Sequence:

  • 使用 JDepend 建立可接受值的閾值,若類別偏離範圍則測試失敗
  • 這是架構師與開發者協作設計 fitness function 的良好範例

架構師必須確保開發者理解 fitness function 的目的,再將其施加於團隊。Fitness function 應像檢查清單(checklist)一樣——簡潔的提醒機制,而非沉重的治理負擔。

ArchUnit(Java)與 NetArchTest(.NET):

  • ArchUnit 是基於 JUnit 的 Java 測試框架,可將治理規則編寫為單元測試
  • 例如:定義分層架構中各層的存取規則,確保 Controller 層不被任何層存取、Persistence 層只能被 Service 層存取
  • NetArchTest 在 .NET 平台提供類似功能

Figure 6.4: Layered architecture

Netflix 的 Simian Army:

  • Conformity Monkey:確保服務遵守架構師定義的治理規則(如回應所有 RESTful verbs)
  • Security Monkey:檢查已知安全缺陷
  • Janitor Monkey:清理不再被路由的孤立服務
  • Chaos Monkey / Chaos Kong:模擬生產環境中的混亂,驗證系統韌性

Chaos engineering 提供了一個重要觀點:問題不是「是否」會發生故障,而是「何時」發生。提前預測並測試這些故障,能讓系統更加強健。