如同建築物可從結構、水電、配線等不同角度檢視,應用架構也是多維度的。軟體架構領域有個重要概念叫 N+1 view model:用 N 個靜態視角(view)描述架構的不同維度,加上一個動態的 scenario view 顯示元素如何互動。每個靜態視角由元素(elements)與關係(relations)組成。
原始的 4+1 view model 由 Phillip Krutchen 提出(《Architectural Blueprints — The 4+1 View Model of Software Architecture》),四個靜態視角為:logical、implementation、process、physical/deployment。本節介紹的是作者改良後、強調微服務面向的 4+1 視角。
本書的 4+1 view model#
四個靜態視角:
- 領域(Domain)視角:程式語言層級的元素(類別、套件等)如何組織為子領域(subdomain),也就是業務功能的切片。
- 元件(Component)視角:子領域如何組織為元件(component,即可部署單元),例如「巨石 vs 微服務」就是元件視角的差異。
- 部署(Deployment)視角:用什麼基礎設施(例如 Kubernetes)來執行與監控元件。
- 建置(Build)視角:程式碼如何從開發者筆電走到生產環境——包含程式碼倉、建置專案、部署管線。
加上 +1 場景視角:用 scenario 描述上述靜態視角的元素如何協作,把架構帶到動態行為層次。

Figure 3.5: My 4+1 view model — domain, component, deployment, build, plus scenario view
領域視角#
主要目的是實作應用的業務領域。
- 視角的元素是程式語言元素(例如 Java 的類別),被組織進子領域(subdomain)。
- 一個子領域是一個業務功能切片,通常由一個小團隊擁有。
- 在物件導向語言中,子領域由類別組成,類別組織進巢狀的 package 結構。
元素之間的關係:
- association、inheritance:類別之間的關係。
- whole-part:package 包含類別與子 package;子領域包含 package。
- uses:子領域之間,A 子領域的類別呼叫 B 子領域的類別。
一個系統操作通常由一個或多個子領域實作。例如 FTGO 的
createOrder()由 Order Management 子領域起始,接著呼叫 Consumer Management 確認消費者可下單,再請 Delivery Management 安排配送。

Figure 3.6: The domain view of the FTGO application, consisting of subdomains and their entities
用六角架構結構化子領域#
子領域聚焦於業務邏輯,但實務上它也包含介面層(web controller)與基礎設施層(資料庫存取)。組織子領域的好做法是六角架構(hexagonal architecture,3.3.2 詳述):
- 子領域的核心是業務邏輯。
- 周圍是介接卡(adapter):
- inbound adapter:從外部接收請求,呼叫業務邏輯,例如 web controller、message handler。
- outbound adapter:從業務邏輯向外發出請求,例如資料庫存取物件、REST API client。
- 應用的領域視角可看成一疊六角形——每個子領域一個。

Figure 3.7: An application's domain view as a stack of hexagons, one per subdomain
領域視角中的元素必須被打包為元件才能上線運行。下一個視角(元件視角)正是處理這件事。
元件視角#
元件視角描述子領域如何被組織為一個或多個元件。
- 元件是特定語言/技術的可執行或可部署單元:例如 Java 元件常是 JAR 或 WAR 檔;其他語言可能是執行檔或一組原始碼;容器映像也勉強算,雖然作者偏好把它視為部署產物。
- 設計元件架構的關鍵決策是:要有幾個元件。
範例:假設 FTGO 有三個子領域(Consumer Management、Order Management、Delivery Management),可能的元件組合包括:
- 三個子領域全打包成單一 FTGO 元件(巨石)。
- Order Service(Order + Delivery)+ Consumer Service。
- 每個子領域各自一個元件:Order Service / Delivery Service / Consumer Service。
- Order Service(Order + Consumer)+ Delivery Service(Delivery)。

Figure 3.8: Two ways of organizing subdomains into components — single component (monolith) vs multiple components (microservice)
第 20 章會說明:先決定「單一元件 vs 多元件」,再決定「每個元件包哪些子領域」。
跨元件的系統操作必須讓元件協作。執行中的元件通常是行程(process),協作多半透過 REST 或 messaging。每個元件都有 API,由其子領域實作:
- API 可定義一個或多個操作供其他元件呼叫。
- API 也可發布事件供其他元件訂閱。
元素之間的關係:
- whole-part:元件包含子領域。
- uses:一個元件呼叫另一個元件的 API。
部署視角#
部署視角描述元件運行於哪些基礎設施之上。
- 元件視角的每個元件,對應到部署視角的一個或多個元件實例,跑在基礎設施元素上。
- 還包含支援基礎設施服務、連接元件的網路資源等。
- 元素類型與關係取決於部署技術。
技術演進:
- 早年:實體伺服器跑元件實例,實體網路相連。
- 現在:多由雲端供應商管理底層硬體;元件跑在虛擬機(VM)、容器(container)、無伺服器函式(serverless function)等高度抽象/虛擬化的元素上。
傳統靠 SSH 或 GUI 控制台手動配置;現代以程式碼定義基礎設施(Infrastructure-as-Code):用 Terraform、CloudFormation 定義雲端資源,用 Kubernetes YAML manifest 定義執行元件的資源,版本化、入庫,工具負責收斂到期望狀態(第 18 章詳述)。
部署架構由品質屬性決定。範例:
- 簡單版(AWS):Elastic Load Balancer 將流量分送到多台 EC2(由 autoscaling group 管理)、單一 Postgres RDS、VPC 提供虛擬網路。可用性與資料庫擴展可能不足。

Figure 3.9: A simple AWS-based deployment of the monolithic FTGO application — ELB, EC2 autoscaling group, RDS, VPC
- 進階版:Kubernetes 叢集跑多個服務,每個服務有自己的資料庫;以 Deployment 與 Pod 管理。
- 更高階版:跨地理區的 Amazon EKS 叢集 + 多個 Aurora RDS,以提升可用性與低延遲存取。
「You are not Google」——不要為了沒有的需求過度設計。選最簡單能滿足當前需求的部署架構。
建置視角#
建置視角描述程式碼從開發者筆電走到生產環境的路徑。元素包括:
- Git 倉庫:存放子領域(領域視角)與基礎設施配置(部署視角)的程式碼。
- 建置專案:每個倉庫中,負責建置與測試元件。
- 部署管線:用建置工具建置與測試元件,通過後部署到生產環境。
部署管線通常由 git push 觸發,也可由其他管線成功完成觸發。
加速建置:incremental builds 與其他技巧#
incremental builds(增量建置):
- 重用前次執行結果,只建置與測試受變更影響的部分。
- 不是新概念——1978 年的 Unix
make工具就有了。現代的 Gradle 把這個概念一般化:Gradle build 是相互依賴的 task graph,每次執行時 Gradle 會判斷哪些 task 已是最新並跳過。
雲端部署管線(例如 GitHub Actions)在短暫環境(ephemeral environments)中執行,需要額外機制(如 build cache)保留前次結果,否則 incremental build 無從發揮。
其他加速技巧:
- 測試套件設計:用測試金字塔(test pyramid)決定不同類型測試的比例(第 15、16 章)。
- 以建置友善的方式設計架構:第 6 章會說明如何結構化巨石的程式碼,以最小化建置期耦合(build-time coupling)。
- 平行化與叢集化:用多執行緒、多機器同時跑測試。
巨石 vs 微服務:建置視角的關鍵差異#
- 巨石:單一倉庫、單一建置專案、單一部署管線——簡單但容易在團隊與程式碼擴張後變成瓶頸,拖慢回饋。

Figure 3.10: Build view for a monolithic architecture — single repository, build project, and deployment pipeline
- 微服務:每個服務有獨立的部署管線(這是定義性特徵),倉庫可獨立也可採 monorepo。每個服務管線縮短前置時間、加快回饋,是微服務的關鍵效益。

Figure 3.11: Build view for microservices — multiple repositories, with one build project and pipeline per repository
+1 場景視角#
四個靜態視角描述結構,但架構不只是靜態結構,還必須描述元素如何互動以滿足需求。第五個視角由 scenario 組成,讓架構「活起來」。
領域、元件、部署視角的場景#
這三個視角的場景,描述元素如何協作以實作系統操作或 user story。
- 領域視角的場景參與者是類別或子領域。
- 元件視角的場景參與者是元件。
- 部署視角的場景參與者是基礎設施元素。
- 有時跨視角的場景特別有用——例如把服務(元件)與其關鍵業務實體(子領域)放在同一個場景裡。
識別「架構顯著場景」#
找出架構顯著場景(architecturally significant scenarios),也就是能展現應用本質、或因技術需求而塑造架構的場景。FTGO 的代表場景就是訂購、準備、配送流程;對其他應用,可能是處理大量資料或有嚴格效能需求的流程。
三種場景視覺化方式#
- UML 序列圖(sequence diagram):列出參與者與互動順序。對 FTGO 的
createOrder(),可顯示 API Gateway、Order Service、Consumer Service、Kitchen Service 之間的互動,以及各服務內部的關鍵類別(Order、Consumer、Restaurant)。

Figure 3.12: A sequence diagram for createOrder() showing API Gateway, Order Service, Consumer Service, Kitchen Service collaboration
- UML 協作圖(collaboration diagram,又稱 communication diagram):參與者位置自由,以編號箭頭表示互動順序;與序列圖功能等價,差異在於它強調參與者,序列圖則強調順序。

Figure 3.13: A collaboration diagram for createOrder()
- 服務藍圖(service blueprint):以使用者旅程為主軸,搭配支撐其的架構元素。例如「下訂單」旅程的第一步,使用者輸入配送地址與時間,對應
updateDeliveryAddress()與findAvailableRestaurants()兩個系統操作,並驅動 ShoppingCart 實體更新與餐廳查詢。

Figure 3.14: A service blueprint for the Create Order customer journey
服務藍圖能把架構直接連結到使用者體驗,適合與非技術利害關係人溝通。可與序列圖、協作圖搭配,提供不同層次的細節。
倉庫與部署管線的場景#
這類場景比領域/元件/部署視角的場景簡單得多——只要描述變更如何從筆電走到生產環境。
- 全自動管線:開發者推送 commit 或合併 PR → 觸發管線 → 部署元件,通常很單純。
- 含手動步驟(例如審核)的管線:可用 activity diagram 視覺化工作流程。
把管線畫成 activity diagram,是優化部署管線很好的第一步——所有手動步驟都會清楚浮現,進而成為自動化的候選。例如 QA review 可用自動化測試取代,PR review 可改為 pair programming 或只保留給高風險變更。