iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
生成式 AI

30 天一人公司的 AI 開發實戰系列 第 20

Day 20: 架構師的決策記錄:為什麼選擇 MADR 來紀錄

  • 分享至 

  • xImage
  •  

前言:那些被遺忘的決策

還記得三個月前,我決定用 SQLDelight 而不是 Room。當時的理由是什麼?為什麼不選擇 Exposed?有考慮過什麼替代方案嗎?

現在的我完全想不起來了。

這就是軟體開發中的「決策健忘症」。我們做了無數個技術決策,但很少記錄「為什麼」。直到有一天:

  • 新人問:「為什麼不用 X 技術?」
  • 自己問:「當初為什麼這樣設計?」
  • AI 助手問:「這個架構決策的背景是什麼?」

這時你才發現,那些關鍵的決策理由都消失在時間的洪流中了。

什麼是 ADR?

ADR (Architecture Decision Records) 是一種輕量級的文件格式,專門用來記錄架構決策的:

  • 背景(Context):為什麼需要做決策?
  • 決策(Decision):決定了什麼?
  • 後果(Consequences):會帶來什麼影響?

簡單來說,ADR 就是架構決策的「日記」。

為什麼選擇 MADR?

市面上有很多 ADR 格式:

  • Michael Nygard 的原始 ADR:最簡單
  • Y-Statements:結構化的決策陳述
  • MADR:Markdown ADR,更豐富的模板
  • ADR Tools:命令列工具生成

我選擇 MADR (Markdown Architectural Decision Records) 的理由:

1. Markdown 原生

# 使用 Clean Architecture 搭配 MVI 模式

* 狀態: 已接受
* 決策者: Sam Zhu
* 日期: 2025-01-11

優點

  • 不需要特殊工具,任何編輯器都能寫
  • Git 友好,可以追蹤變更歷史
  • 易於閱讀,格式清晰
  • AI 助手能直接理解和生成

2. 結構完整但不繁瑣

MADR 的模板剛剛好:

## 背景與問題陳述
[為什麼需要做決策]

## 決策驅動因素
* [關鍵考量點]

## 考慮的選項
* [選項 1]
* [選項 2]

## 決策結果
選擇 [選項 X],因為...

## 後果
### 正面影響
### 負面影響

不會太簡單(缺少重要資訊),也不會太複雜(寫到不想寫)。

3. 支援演化

MADR 有狀態管理:

* 狀態: [草案 | 提議 | 已接受 | 已棄用 | 已拒絕]

決策可以演化:

  • 草案:還在思考
  • 提議:徵求意見
  • 已接受:正式採用
  • 已棄用:被新決策取代
  • 已拒絕:評估後不採用

實戰案例:SQLDelight Migration 決策

讓我用實際的 MADR 來展示它的威力:

# 使用 SQLDelight 內建 Migration 管理資料庫版本

* 狀態: 已接受
* 決策者: Sam Zhu, Claude (AI Assistant)
* 日期: 2025-01-11
* 技術故事: 需要支援資料庫結構演進,用戶升級時自動遷移

## 背景與問題陳述

Grimo 採用 SQLDelight 作為資料庫層,隨著功能迭代,
資料庫結構會持續演進。我們需要一個可靠的機制來:

1. 管理資料庫版本
2. 自動執行結構遷移
3. 確保資料完整性
4. 支援向後相容

SQLDelight 2.0+ 提供了內建的 migration 支援,
但也可以選擇自行實作或使用第三方方案。

## 決策驅動因素

* **簡單性**:減少外部依賴和複雜度
* **類型安全**:與 SQLDelight 的類型系統整合
* **可測試性**:能夠測試 migration 邏輯
* **跨平台**:支援 KMP 所有目標平台
* **官方支援**:有長期維護保證

## 考慮的選項

### 選項 1: SQLDelight 內建 Migration
使用 `deriveSchemaFromMigrations = true` 和 `.sqm` 檔案

**優點**:
- 與 SQLDelight 深度整合
- 編譯時驗證
- 自動產生 Schema

**缺點**:
- 文件相對較少
- 靈活性受限

### 選項 2: 自訂 Migration 系統
建立自己的版本管理和執行機制

**優點**:
- 完全控制
- 可自訂邏輯

**缺點**:
- 需要大量開發
- 容易出錯
- 測試負擔重

### 選項 3: Flyway/Liquibase
使用成熟的第三方 migration 工具

**優點**:
- 功能豐富
- 社群支援好

**缺點**:
- JVM only,不支援 KMP
- 額外依賴
- 與 SQLDelight 整合困難

## 決策結果

選擇 **選項 1: SQLDelight 內建 Migration**。

理由:
1. 與現有技術棧完美整合
2. 編譯時驗證減少執行時錯誤
3. 支援所有 KMP 平台
4. 維護成本最低
5. 官方持續改進

## 後果

### 正面影響
* 開發速度快,一週內完成實作
* 類型安全,編譯時發現問題
* 與 CI/CD 整合簡單
* 減少專案依賴

### 負面影響
* 需要學習 SQLDelight 特定語法
* 複雜 migration 可能需要 workaround
* 文件和範例相對較少

## 確認

透過以下方式確認決策實施:
1. 所有 migration 測試通過
2. 從 v1 成功升級到 v3
3. 效能符合預期(< 5秒)
4. 程式碼審查通過

## 參考資料
* [SQLDelight 2.0 Migration 文件](https://cashapp.github.io/sqldelight/2.0.0/jvm_sqlite/migrations/)
* [GitHub Issue #2211](https://github.com/cashapp/sqldelight/issues/2211)

MADR 的實際效益

1. 知識傳承

三個月後,當我(或其他人)看到這份 MADR:

Q: 為什麼不用 Flyway?
A: 看 MADR - 因為不支援 KMP

Q: 有什麼缺點需要注意?
A: 看 MADR - 複雜 migration 可能需要 workaround

Q: 當初還考慮過什麼?
A: 看 MADR - 自訂系統和第三方工具

2. 避免重複討論

新人:「我覺得應該用 Room...」
我:「請先看 ADR-002,裡面有完整評估」
新人:「哦,原來已經討論過了」

3. AI 助手的知識庫

我:請根據 ADR-002 幫我實作新的 migration
Claude:根據 ADR-002,我們使用 SQLDelight 內建 migration,
       需要在 migrations/ 目錄建立 .sqm 檔案...

建立 MADR 的最佳實踐

1. 何時寫 MADR?

不是所有決策都需要 MADR。判斷的標準很簡單:

如果影響整個系統,需要 MADR。如果只影響單一模組但難以改變,也需要 MADR。如果改變成本很高,同樣需要 MADR。其他情況通常不需要。

需要 MADR 的例子

  • 選擇架構模式(Clean Architecture)
  • 選擇核心框架(KMP、SQLDelight)
  • 重要的設計模式(Event Sourcing)

不需要 MADR 的例子

  • 函式命名規則
  • 小工具類的實作方式
  • UI 顏色選擇

2. 如何寫好 MADR?

好的寫法:

## 背景與問題陳述
隨著團隊規模擴大,程式碼風格不一致問題日益嚴重,
PR review 時常因格式問題產生討論,影響開發效率。

不好的寫法:

## 背景與問題陳述
程式碼很亂。

3. MADR 的生命週期

MADR 文件有清晰的生命週期:從草案開始,識別問題後完成評估變成提議,團隊同意後變成已接受,或者被否決成為已拒絕。已接受的決策可能被新的 ADR 取代而變成已棄用。

4. 編號系統

0001-use-clean-architecture-with-mvi.md
0002-use-sqldelight-migration.md
0003-adopt-ktfmt-for-code-formatting.md
  • 4 位數編號,從 0001 開始
  • 使用 kebab-case 命名
  • 簡短但描述性的標題

整合 MADR 到開發流程

1. 決策前:評估模板

# 創建新的 MADR
cp docs/architecture/09-decisions/template.md \
   docs/architecture/09-decisions/0003-new-decision.md

2. 決策中:協作討論

* 狀態: 提議  # 開放討論
* 決策者: Sam Zhu, Team
* 日期: 2025-01-20

## 評論
- @alice: 選項 2 的成本是否評估過?
- @bob: 建議加入效能考量

3. 決策後:執行追蹤

## 確認
- [x] 技術 POC 完成
- [x] 團隊 training 完成
- [ ] 生產環境部署
- [ ] 監控指標設定

MADR + AI = 決策加速器

AI 輔助撰寫 MADR

我:幫我評估是否應該從 REST 改為 GraphQL
Claude:我來幫你撰寫 MADR 草案:

# 從 REST API 遷移到 GraphQL

## 背景與問題陳述
目前的 REST API 存在以下問題:
1. Over-fetching:獲取不需要的資料
2. Under-fetching:需要多次請求
3. 版本管理複雜

## 考慮的選項
1. 保持 REST + 優化
2. 遷移到 GraphQL
3. 採用 gRPC
[繼續生成完整評估...]

AI 審查 MADR

我:請審查這份 MADR 是否完整
Claude:審查 MADR-0004:
缺少的部分:
1. 沒有評估遷移成本
2. 缺少效能影響分析
3. 未考慮團隊學習曲線

一人公司的 MADR 實踐

挑戰:沒有團隊討論

解法:與 AI 和未來的自己對話

* 決策者: Sam Zhu, Claude (AI), Future Sam

挑戰:容易偷懶不寫

解法:簡化模板,只寫關鍵部分

# 快速 MADR

## 為什麼
[一句話說明問題]

## 選項
1. [選項 A]
2. [選項 B]

## 決定
[選擇] 因為 [原因]

## 風險
[主要風險]

挑戰:不知道寫什麼

解法:問自己三個問題

  1. 六個月後的我會問什麼?
  2. 如果要向別人解釋,會說什麼?
  3. 如果重來一次,需要知道什麼?

MADR 是架構的「備忘錄」

MADR 不是官僚文件,而是:

  • 決策的快照:記錄當時的思考脈絡
  • 知識的地圖:避免重複踩坑
  • 溝通的橋樑:減少無謂的討論
  • 學習的資產:累積架構智慧

對一人公司特別重要,因為:

  • 你既是決策者也是執行者
  • 沒有團隊幫你記住決策
  • 未來的你會感謝現在的你
  • AI 助手需要了解你的決策邏輯

記住:最好的 MADR 是寫下來的 MADR,而不是完美的 MADR。

今日金句

「程式碼展示『如何做』,MADR 記錄『為何這樣做』。」

關於作者:Sam,一人公司創辦人。正在打造 Grimo,一個智能任務管理和分配平台。

專案連結GitHub - grimostudio


上一篇
Day 19: 開發工程師接任務:依據 Task 開工並檢驗完成,維護文件一致性
下一篇
Day 21: 創辦人週報:好的流程讓一人公司也能高效運轉
系列文
30 天一人公司的 AI 開發實戰21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言