設計模式:不要為了用而用
什麼時候「不需要」設計模式?
// ❌ 過度設計:三行邏輯套了 Strategy Pattern
public interface IGreetingStrategy { string Greet(string name); }
public class MorningGreeting : IGreetingStrategy { public string Greet(string name) => $"早安 {name}"; }
public class EveningGreeting : IGreetingStrategy { public string Greet(string name) => $"晚安 {name}"; }
public class GreetingContext { ... }
// ✅ 簡單就好
string Greet(string name, bool isMorning) => isMorning ? $"早安 {name}" : $"晚安 {name}";
先寫出能動的程式碼,遇到痛點時再用模式解決。
最常用的 5 個模式(實際場景)
1. Strategy — 行為可替換
場景:支付方式(信用卡、Line Pay、Apple Pay)
痛點:if-else 越來越多,每次加支付方式都要改核心程式碼
解法:每種支付方式是一個 Strategy,OrderService 只依賴介面
2. Factory — 建立物件的邏輯複雜
場景:根據設定檔決定要用 SQL Server 還是 PostgreSQL
痛點:建立 DbContext 需要很多參數和判斷
解法:Factory 封裝建立邏輯,呼叫端只需要 factory.Create()
3. Observer — 事件通知
場景:訂單成立後要寄信、推播、記 log、更新庫存
痛點:OrderService 直接呼叫 4 個 Service,耦合嚴重
解法:OrderService 發出事件,各個 Observer 各自處理
(C# 中用 event、MediatR、或訊息佇列)
4. Decorator — 替現有功能加料
場景:Repository 加快取、加 log、加重試
痛點:不想改原本的 Repository 程式碼
解法:CachingRepository 包住原本的 Repository
5. Builder — 建立複雜物件
場景:建立一封 Email(有收件人、主旨、本文、附件、CC、BCC...)
痛點:建構函式參數太多
解法:EmailBuilder.To(...).Subject(...).Body(...).Build()
判斷要不要用模式
1. 這段程式碼現在有什麼問題?(不是「未來可能有」)
2. 用了模式會更好讀嗎?(還是更難懂?)
3. 團隊能理解嗎?(如果只有你懂,那是壞的架構)
最好的程式碼不是用了最多模式的,而是最容易理解的。