程式碼重構技能
描述
主動偵測並執行程式碼重構,維持 DDD 架構和程式碼品質。
觸發條件
-
「重構這段程式碼」、「refactor」
-
「這個檔案太長了」
-
「模組化」、「拆分」
-
主動觸發:偵測到程式碼超過閾值時
核心原則
📜 依據憲法第 7.3 條「主動重構原則」
重構不是改天換地,而是持續的小步快跑 每次提交都應該比上次更乾淨
閾值設定
📏 長度閾值
類型 警告 強制重構
檔案
200 行 400 行
類別
150 行 300 行
函數
30 行 50 行
目錄檔案數
10 個 15 個
🔄 複雜度閾值
指標 警告 強制重構
圈複雜度
10 15
巢狀深度
3 層 4 層
參數數量
4 個 6 個
依賴數量
5 個 8 個
重構模式庫
1️⃣ Extract Method(提取方法)
觸發條件:函數過長、重複邏輯
Before
def process_order(order): # 驗證訂單 (10 行) if not order.items: raise ValueError("Empty order") if order.total < 0: raise ValueError("Invalid total") # ... 更多驗證
# 計算價格 (15 行)
subtotal = sum(item.price * item.qty for item in order.items)
tax = subtotal * 0.05
total = subtotal + tax
# ... 更多計算
# 儲存訂單 (10 行)
# ...
After
def process_order(order): self._validate_order(order) total = self._calculate_total(order) self._save_order(order, total)
def _validate_order(self, order): """驗證訂單有效性""" if not order.items: raise ValueError("Empty order") # ...
def _calculate_total(self, order) -> Decimal: """計算訂單總金額(含稅)""" subtotal = sum(item.price * item.qty for item in order.items) return subtotal * Decimal("1.05")
2️⃣ Extract Class(提取類別)
觸發條件:類別職責過多、超過 150 行
Before: User 類別包含太多職責
class User: def init(self, name, email, ...): self.name = name self.email = email self.address_line1 = ... self.address_line2 = ... self.city = ... self.postal_code = ...
def validate_email(self): ...
def format_address(self): ...
def calculate_shipping(self): ...
After: 提取 Address 值物件
@dataclass(frozen=True) class Address: """地址值物件""" line1: str line2: str | None city: str postal_code: str
def format(self) -> str:
return f"{self.line1}\n{self.city} {self.postal_code}"
class User: def init(self, name: str, email: Email, address: Address): self.name = name self.email = email self.address = address
3️⃣ Replace Conditional with Polymorphism(多態取代條件)
觸發條件:大量 if-elif-else 或 switch
Before: 條件地獄
def calculate_shipping(order): if order.shipping_type == "standard": return order.weight * 10 elif order.shipping_type == "express": return order.weight * 25 + 50 elif order.shipping_type == "overnight": return order.weight * 50 + 100 elif order.shipping_type == "international": # 複雜計算... pass
After: 策略模式
class ShippingStrategy(ABC): @abstractmethod def calculate(self, order) -> Decimal: ...
class StandardShipping(ShippingStrategy): def calculate(self, order) -> Decimal: return order.weight * 10
class ExpressShipping(ShippingStrategy): def calculate(self, order) -> Decimal: return order.weight * 25 + 50
使用
shipping_strategies = { "standard": StandardShipping(), "express": ExpressShipping(), # ... } cost = shipping_strategies[order.shipping_type].calculate(order)
4️⃣ Introduce Parameter Object(參數物件)
觸發條件:參數超過 4 個
Before: 參數過多
def create_user( name: str, email: str, phone: str, address_line1: str, address_line2: str, city: str, postal_code: str, country: str, ): ...
After: 使用參數物件
@dataclass class CreateUserCommand: name: str email: str phone: str address: Address
def create_user(command: CreateUserCommand): ...
5️⃣ Split Module(拆分模組)
觸發條件:目錄超過 10 個檔案
Before
src/Domain/ ├── User.py ├── Order.py ├── Product.py ├── Payment.py ├── Shipping.py ├── Review.py ├── Coupon.py ├── Notification.py ├── ... # 太多了!
After: 按子領域拆分
src/Domain/ ├── Identity/ │ └── User.py ├── Ordering/ │ ├── Order.py │ └── Payment.py ├── Catalog/ │ ├── Product.py │ └── Review.py ├── Promotion/ │ └── Coupon.py └── Communication/ └── Notification.py
DDD 架構守護
重構時必須檢查是否違反 DDD 原則:
❌ 常見違規
違規 1: Domain 層依賴 Infrastructure
Domain/Services/OrderService.py
from infrastructure.database import db # ❌ 禁止!
違規 2: Presentation 直接存取 Domain
Presentation/API/routes.py
from domain.repositories import UserRepository # ❌ 應透過 Application
違規 3: Entity 包含持久化邏輯
class User: def save(self): # ❌ 應在 Repository db.session.add(self)
✅ 正確依賴方向
Presentation → Application → Domain ↓ Infrastructure
重構流程
1️⃣ 偵測階段
🔍 偵測到重構需求:
- 檔案:
src/domain/services/order_service.py - 問題:檔案長度 342 行(超過 200 行警告閾值)
- 複雜度:圈複雜度 12(超過 10 警告閾值)
2️⃣ 分析階段
📊 分析結果:
process_order()函數 85 行,建議拆分- 發現 3 處重複邏輯,建議提取
- 識別出 2 個隱藏的 Value Object
3️⃣ 規劃階段
📋 重構計畫:
- 提取
OrderValidator類別 - 提取
PricingCalculator服務 - 建立
OrderStatusValue Object - 更新測試確保覆蓋
4️⃣ 執行階段
🔧 執行重構:
- 建立
OrderValidator類別 - 遷移驗證邏輯
- 更新測試
- 確認測試通過
- 提取
PricingCalculator - ...
5️⃣ 驗證階段
✅ 重構完成:
- 測試:全部通過(42/42)
- 覆蓋率:85%(+3%)
- 複雜度:8(-4)
- 架構:符合 DDD ✓
主動建議範本
當偵測到需要重構時,AI 應主動建議:
💡 重構建議
偵測到 order_service.py 已達 250 行,建議進行模組化:
建議拆分方案
| 新檔案 | 內容 | 行數 |
|---|---|---|
order_validator.py | 訂單驗證邏輯 | ~50 行 |
pricing_calculator.py | 價格計算邏輯 | ~60 行 |
order_service.py | 服務編排 | ~80 行 |
預期效益
- ✅ 單一職責原則
- ✅ 更易測試
- ✅ 降低認知負荷
是否要我執行這個重構?
與其他 Skills 整合
Skill 整合方式
code-reviewer
審查時觸發重構建議
test-generator
重構前先生成測試
ddd-architect
確保重構符合 DDD
memory-updater
記錄重構決策