249 lines
6.5 KiB
Markdown
249 lines
6.5 KiB
Markdown
# 🛡️ 架構防護檢查清單
|
||
|
||
## 📋 **每次開發前必讀**
|
||
|
||
### 🎯 **功能開發前的架構決策**
|
||
|
||
```
|
||
❓ 我要開發的功能屬於哪個領域?
|
||
📚 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%
|
||
```
|
||
|
||
### **📈 追蹤方式**
|
||
```bash
|
||
# 快速檢查命令
|
||
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)}')"
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 **實用工具**
|
||
|
||
### **架構決策模板**
|
||
```markdown
|
||
# 新功能架構決策
|
||
|
||
## 功能描述
|
||
簡述要實現的功能
|
||
|
||
## 架構選擇
|
||
- [ ] 使用現有服務
|
||
- [ ] 擴展現有服務
|
||
- [ ] 創建新服務
|
||
|
||
## 服務歸屬
|
||
- [ ] Domain/Learning
|
||
- [ ] Domain/Analysis
|
||
- [ ] Domain/User
|
||
- [ ] Infrastructure/*
|
||
|
||
## 依賴分析
|
||
列出需要依賴的其他服務,確認依賴方向正確
|
||
|
||
## 測試計劃
|
||
描述如何測試新功能
|
||
```
|
||
|
||
### **重構安全清單**
|
||
```markdown
|
||
# 重構前準備
|
||
- [ ] 現有功能有足夠測試覆蓋
|
||
- [ ] 識別所有受影響的代碼
|
||
- [ ] 準備回滾方案
|
||
|
||
# 重構中執行
|
||
- [ ] 小步驟,頻繁提交
|
||
- [ ] 每步都保持測試通過
|
||
- [ ] 保持 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: 考慮建立協調服務或使用事件驅動模式
|
||
```
|
||
|
||
---
|
||
|
||
**記住**: 好的架構是團隊的共同責任,每個人都要參與維護! |