設計模式簡介
設計模式(Design Pattern)是解決常見程式設計問題的通用方案。
它不是程式碼本身,而是一種指導如何編寫程式碼的方式。
設計模式分為三大類:
- 創建型模式(Creational Patterns)
- 結構型模式(Structural Patterns)
- 行為型模式(Behavioral Patterns)
類型 | 目的 | 範例 |
---|---|---|
創建型模式 | 解決如何建立物件的問題,提供更好的方式來建立和管理物件。 | 單例模式(Singleton)、工廠模式(Factory) |
結構型模式 | 關注類與物件之間的組合,確保系統結構靈活且易於擴展。 | 裝飾器模式(Decorator)、代理模式(Proxy) |
行為型模式 | 處理類或物件之間的責任分配及通訊協作,定義如何進行互動。 | 觀察者模式(Observer)、命令模式(Command) |
簡單實例解釋
1. 單例模式(Singleton Pattern)
確保某個類別只有一個實例,並提供全域存取點。
適用場景:
- 資料庫連線物件。
- 設定檔管理器。
public class Singleton
{
private static Singleton _instance;
// 私有建構子,防止外部實例化
private Singleton() { }
// 提供全域存取的靜態方法
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
public void DoSomething()
{
Console.WriteLine("單例模式運行中...");
}
}
// 測試
public class Program
{
public static void Main()
{
Singleton instance1 = Singleton.Instance;
Singleton instance2 = Singleton.Instance;
Console.WriteLine(instance1 == instance2); // True
instance1.DoSomething();
}
}
2. 工廠模式(Factory Pattern)
定義一個用於創建物件的介面,而讓子類決定要實例化哪個類別。工廠方法將物件創建的細節與使用者分離。
適用場景:
- 根據條件建立不同類型的物件。
- 例如:支付系統中,建立不同的付款方式(信用卡、PayPal)。
// 付款方式介面
public interface IPayment
{
void Pay(decimal amount);
}
// 信用卡付款實現
public class CreditCardPayment : IPayment
{
public void Pay(decimal amount)
{
Console.WriteLine($"使用信用卡付款: {amount} 元");
}
}
// PayPal 付款實現
public class PayPalPayment : IPayment
{
public void Pay(decimal amount)
{
Console.WriteLine($"使用 PayPal 付款: {amount} 元");
}
}
// 工廠類別
public class PaymentFactory
{
public static IPayment CreatePayment(string type)
{
return type switch
{
"CreditCard" => new CreditCardPayment(),
"PayPal" => new PayPalPayment(),
_ => throw new ArgumentException("不支援的付款方式")
};
}
}
// 測試
public class Program
{
public static void Main()
{
IPayment payment = PaymentFactory.CreatePayment("CreditCard");
payment.Pay(1000);
payment = PaymentFactory.CreatePayment("PayPal");
payment.Pay(500);
}
}
3. 觀察者模式(Observer Pattern)
定義一種一對多的依賴關係,當一個物件的狀態改變時,所有依賴它的物件都會自動收到通知並更新。
適用場景:
- 訂閱通知系統(如新聞推播、股票價格變化)。
// 觀察者介面
public interface IObserver
{
void Update(string message);
}
// 主題類別(被觀察者)
public class Subject
{
private readonly List<IObserver> _observers = new();
public void AddObserver(IObserver observer)
{
_observers.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
_observers.Remove(observer);
}
public void NotifyObservers(string message)
{
foreach (var observer in _observers)
{
observer.Update(message);
}
}
}
// 具體觀察者
public class User : IObserver
{
private readonly string _name;
public User(string name)
{
_name = name;
}
public void Update(string message)
{
Console.WriteLine($"{_name} 收到通知: {message}");
}
}
// 測試
public class Program
{
public static void Main()
{
Subject subject = new();
User user1 = new("Alice");
User user2 = new("Bob");
subject.AddObserver(user1);
subject.AddObserver(user2);
subject.NotifyObservers("有新的消息發布!");
subject.RemoveObserver(user1);
subject.NotifyObservers("只有 Bob 會收到這條消息。");
}
}
如何選擇設計模式?
- 創建型模式:
- 如果需要靈活建立物件,例如根據不同條件建立不同類型的物件。
- 範例:工廠模式。
- 結構型模式:
- 如果需要解決物件與物件之間的組合問題,例如新增功能時不影響核心邏輯。
- 範例:裝飾器模式。
- 行為型模式:
- 如果需要管理物件之間的互動或流程,例如事件通知或執行順序。
- 範例:觀察者模式。
學習與實踐建議
- 從問題出發:
- 思考實際開發中遇到的問題,選擇適合的模式。
- 閱讀經典書籍:
- 《設計模式:可復用面向物件軟體的基礎》(Design Patterns: Elements of Reusable Object-Oriented Software)。
- 動手實作:
- 嘗試用每個設計模式解決簡單的實際問題,加深理解。
結論
設計模式不是硬性規範,而是幫助我們解決常見問題的「工具箱」。靈活選擇模式,將能有效提升程式碼的品質與維護性!