系統架構與資料流
決定系統邊界、模組責任、資料狀態,以及各部分如何一起運作
決定系統邊界、模組責任、資料狀態,以及各部分如何一起運作
架構設計的輸入
- 需求、使用情境與核心領域規則
- 資料量、流量、延遲與可用性目標
- 資安、法規、個資與稽核要求
- 現有系統、團隊能力、預算與交付期限
- 預期會改變的部分與可以暫時接受的限制
System Context:先畫邊界
- 系統服務哪些使用者與角色?
- 依賴哪些資料庫、API、檔案與外部服務?
- 哪些資料進來、哪些結果出去?
- 誰負責驗證身分、保存狀態與處理失敗?
- 系統外的責任不要誤畫成系統內功能
從 Monolith 到 Service
| 選擇 | 常見情境 |
|---|---|
| 單一應用程式 | 團隊小、需求仍在探索、部署簡單 |
| 模組化 Monolith | 需要清楚邊界,但不想承擔分散式成本 |
| Microservices | 團隊與服務需要獨立擴展、部署或治理 |
| Serverless/Managed Service | 希望降低基礎設施維運負擔 |
不是拆得越多越先進。
Module、Component 與 Responsibility
- 每個模組負責什麼、不負責什麼?
- 對外提供哪些 interface?
- 哪些資料可以直接存取,哪些只能透過服務?
- 修改一條規則需要碰多少模組?
- 循環相依、共享狀態與跨層呼叫都是警訊
資料模型與狀態
- Entity、value object、identifier 與 relationship
- Schema、constraint、index 與資料型別
- 狀態如何建立、修改、封存與刪除
- Transaction、consistency、concurrency 與 idempotency
- Schema migration 與舊資料相容策略
資料流怎麼畫?
使用者請求
→ API/UI 入口
→ 驗證與授權
→ 商業規則
→ 資料庫/外部服務
→ 回傳結果或發出事件
同時標出狀態改變、副作用、錯誤與重試位置。
API Contract
- Endpoint、method、request、response、status code
- Validation、error model 與版本相容性
- Authentication、authorization 與 rate limit
- Pagination、filter、sorting 與 bulk operation
- OpenAPI、schema 或 contract test 作為共同依據
同步、非同步與事件
| 模式 | 主要考量 |
|---|---|
| 同步呼叫 | 簡單直接,但呼叫者要等待與承擔失敗 |
| Queue/Job | 可削峰與重試,但需要追蹤狀態 |
| Event-driven | 降低耦合,但順序、重複與一致性更複雜 |
| Batch | 適合大量處理,但即時性較低 |
失敗不是例外路徑
- Timeout、retry、backoff、circuit breaker
- Partial failure 與 compensating action
- Duplicate message 與 idempotency key
- Graceful degradation 與 fallback
- 失敗後資料是否一致、使用者是否知道目前狀態
Non-functional Architecture
- Performance:latency、throughput、resource usage
- Availability:redundancy、failover、recovery
- Scalability:水平/垂直擴展與瓶頸
- Security:trust boundary、least privilege、audit
- Operability:deploy、observe、debug、backup、restore
ADR:把重要選擇留下來
Context:當時的條件與問題
Decision:選擇了什麼
Alternatives:還比較過哪些方案
Consequences:得到什麼,也付出什麼
Revisit when:什麼條件出現時重新評估
架構 Review 常問什麼?
- 關鍵假設有沒有證據?
- 單點故障與權限邊界在哪裡?
- 需求變更時哪個部分最先承受壓力?
- 失敗、復原與資料 migration 是否可行?
- 團隊真的有能力維運這個設計嗎?
看到 Agent 修改架構時
至少要追問它改了哪些 boundary、contract、state 與 dependency,
以及支持這張架構圖的 Code、設定、測試或 trace 在哪裡。