dramaling-vocab-learning/note/done/ARCHITECTURE_CHECKLIST.md

6.5 KiB

🛡️ 架構防護檢查清單

📋 每次開發前必讀

🎯 功能開發前的架構決策

❓ 我要開發的功能屬於哪個領域?
   📚 Learning (詞卡、學習、複習)
   🤖 Analysis (AI分析、詞彙分析)
   👤 User (用戶管理、認證、設定)
   🔧 Infrastructure (快取、外部服務)

❓ 是否需要新的服務?
   ✅ 新業務領域 → 創建新服務
   ✅ 現有服務職責過重 → 拆分服務
   ❌ 只是小修改 → 擴展現有服務

❓ 服務應該放在哪一層?
   🏢 Domain/: 核心業務邏輯
   🔧 Infrastructure/: 技術實現
   🤝 Shared/: 跨領域工具

代碼提交前檢查清單

🏗️ 架構規則檢查

服務設計

  • 服務職責單一: 只做一件事,做好它
  • 有介面定義: 每個服務都有對應的 I*Service 介面
  • 命名清晰: 服務名稱表達業務意圖
  • 大小適中: 服務文件 < 300 行(建議 < 200 行)

依賴關係

  • 向上依賴: Domain → Infrastructure → Shared
  • 無循環依賴: 服務間不相互依賴
  • 介面隔離: 只依賴需要的介面方法
  • 控制器分離: Controller 不直接調用 Repository

代碼品質

  • 異常處理: 適當的 try-catch 和日誌記錄
  • 參數驗證: 公共方法驗證參數
  • 資源管理: using 語句管理 IDisposable
  • 命名規範: 變數和方法名有意義

🚨 危險信號警報

立即停止的架構違規

🚨 Controller 直接使用 DbContext
   → 應該通過 Service 層

🚨 Domain Service 依賴 Infrastructure Service
   → 依賴方向錯誤

🚨 服務文件超過 500 行
   → 立即拆分

🚨 發現 "Manager"、"Helper"、"Utils" 類別
   → 重新設計為 Service

🚨 業務邏輯在 Controller 中
   → 移到對應的 Domain Service

⚠️ 需要注意的架構問題

⚠️ 方法超過 20 行
   → 考慮拆分為更小的方法

⚠️ 類別超過 10 個公共方法
   → 考慮是否職責過多

⚠️ 構造函數參數超過 5 個
   → 可能依賴過多,考慮重構

⚠️ 重複的錯誤處理代碼
   → 考慮建立統一的錯誤處理機制

🎯 快速自檢方法

1. 服務職責檢查

問自己:
1. 這個服務的職責能用一句話說清楚嗎?
2. 如果要給新人解釋這個服務,需要多長時間?
3. 這個服務是否混合了多個業務領域的邏輯?

✅ 好的例子:
"FlashcardService 負責詞卡的創建、更新和學習推薦"

❌ 壞的例子:
"UserFlashcardAnalysisService 負責用戶管理、詞卡操作、AI分析和快取管理"

2. 依賴關係檢查

快速檢查:
1. 打開服務文件,看 using 語句
2. 檢查構造函數參數
3. 確認沒有向下依賴

✅ 正確依賴:
FlashcardService 依賴 IFlashcardRepository
AnalysisService 依賴 ICacheService

❌ 錯誤依賴:
CacheService 依賴 FlashcardService
Repository 依賴 AnalysisService

3. 測試友好度檢查

問自己:
1. 這個服務容易寫單元測試嗎?
2. 所有依賴都是可以模擬的介面嗎?
3. 方法的輸入輸出是否清晰明確?

✅ 測試友好:
public async Task<FlashcardDto> CreateFlashcardAsync(CreateFlashcardRequest request)

❌ 測試困難:
public async Task DoComplexFlashcardOperation(object data, bool flag1, bool flag2)

📊 架構品質指標

🎯 目標指標

服務數量: 目標 8-15 個核心服務
平均服務大小: < 200 行
介面覆蓋率: > 90%
依賴深度: < 4 層
快取命中率: > 80%

📈 追蹤方式

# 快速檢查命令
echo "服務數量: $(find backend/DramaLing.Api/Services -name "*Service.cs" | wc -l)"
echo "介面數量: $(find backend/DramaLing.Api/Services -name "I*Service.cs" | wc -l)"
echo "平均文件大小: $(find backend/DramaLing.Api/Services -name "*.cs" -exec wc -l {} + | awk '{sum+=$1; count++} END {print int(sum/count)}')"

🔧 實用工具

架構決策模板

# 新功能架構決策

## 功能描述
簡述要實現的功能

## 架構選擇
- [ ] 使用現有服務
- [ ] 擴展現有服務
- [ ] 創建新服務

## 服務歸屬
- [ ] Domain/Learning
- [ ] Domain/Analysis
- [ ] Domain/User
- [ ] Infrastructure/*

## 依賴分析
列出需要依賴的其他服務,確認依賴方向正確

## 測試計劃
描述如何測試新功能

重構安全清單

# 重構前準備
- [ ] 現有功能有足夠測試覆蓋
- [ ] 識別所有受影響的代碼
- [ ] 準備回滾方案

# 重構中執行
- [ ] 小步驟,頻繁提交
- [ ] 每步都保持測試通過
- [ ] 保持 API 兼容性

# 重構後驗證
- [ ] 功能完全正常
- [ ] 性能沒有退化
- [ ] 文檔已更新

🎓 最佳實踐總結

👍 推薦做法

  1. 先設計介面,後實作: 確保 API 設計合理
  2. 小服務優於大服務: 職責單一,更容易維護
  3. 依賴注入: 所有依賴通過構造函數注入
  4. 異步優先: 所有 I/O 操作使用 async/await
  5. 日誌記錄: 關鍵操作要有適當日誌

👎 避免做法

  1. 靜態依賴: 避免 static 類別和方法
  2. 直接數據訪問: Controller 不直接操作數據庫
  3. 過度抽象: 不要為了抽象而抽象
  4. 忽略異常: 不要吞掉異常
  5. 魔法數字: 避免硬編碼的數值和字串

📞 獲得幫助

遇到架構問題時

  1. 查閱文檔: 先查看 ARCHITECTURE_GOVERNANCE.md
  2. 檢查現有模式: 看看類似功能是如何實現的
  3. 架構審查: 與團隊討論架構決策
  4. 逐步實施: 不確定時先小範圍實驗

常見問題 FAQ

Q: 我的服務變得很大,該怎麼辦?
A: 按職責拆分,一個服務只負責一個業務領域

Q: 我需要在服務間共享代碼,該怎麼辦?
A: 考慮建立 Shared 服務或抽取到基類

Q: 我的 Controller 邏輯很複雜,該怎麼辦?
A: 將業務邏輯移到對應的 Domain Service

Q: 我需要跨多個服務的操作,該怎麼辦?
A: 考慮建立協調服務或使用事件驅動模式

記住: 好的架構是團隊的共同責任,每個人都要參與維護!