1 定義
觀察者模式也稱作發布/訂閱模式,提供了一種作用於任何實現了訂閱者接口的對象的機制, 可對其事件進行訂閱和取消訂閱。
2 例子
假如你有兩種類型的對象: 顧客和商店。顧客希望商店某些商品有優惠信息的時候可以通知顧客。在這個例子中商店就是發布者,顧客就是訂閱者。商店發布通知,維護訂閱及取消訂閱對象,如果顧客訂閱了,則商店發布通知后顧客進行相應的處理。
3 實現
首先,聲明訂閱者接口。
//聲明訂閱者接口。
public interface IObserver
{
// 通知后處理
void Handle(ISubject subject);
}
然后,聲明發布者接口並定義一些接口來在列表中添加和刪除訂閱對象。
public interface ISubject
{
// 訂閱
void Subscribe(IObserver observer);
// 取消訂閱
void Unsubscribe(IObserver observer);
// 發布
void Publish();
}
接着,創建具體發布者類。
//創建具體發布者類。
public class Subject : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
public void Subscribe(IObserver observer)
{
this._observers.Add(observer);
}
public void Unsubscribe(IObserver observer)
{
this._observers.Remove(observer);
}
public void Publish()
{
Console.WriteLine("商店發布優惠通知!");
foreach (var observer in _observers)
{
observer.Handle(this);
}
}
}
接着,創建具體顧客類,顧客A和顧客B。
//具體訂閱者類中實現通知后處理的方法。
public class CustomerA : IObserver
{
public void Handle(ISubject subject)
{
Console.WriteLine("顧客A收到優惠通知。");
}
}
public class CustomerB : IObserver
{
public void Handle(ISubject subject)
{
Console.WriteLine("顧客B收到優惠通知。");
}
}
最后,創建客戶端類。
//客戶端必須生成所需的全部訂閱者, 並在相應的發布者處完成注冊工作。
class Program
{
static void Main(string[] args)
{
var subject = new Subject();
var observerA = new CustomerA();
subject.Subscribe(observerA);
var observerB = new CustomerB();
subject.Subscribe(observerB);
subject.Publish();
Console.WriteLine();
subject.Unsubscribe(observerB);
subject.Publish();
Console.ReadKey();
}
}
讓我們來看看輸出結果:
商店發布優惠通知!
顧客A收到優惠通知。
顧客B收到優惠通知。
商店發布優惠通知!
顧客A收到優惠通知。
4 用.NET的事件模型來實現
.NET的事件模型是一種典型的觀察者模型,代碼相對來說更加簡潔。
//創建具體發布者類。
public class Subject
{
public event Action Handles;
public void Publish()
{
Console.WriteLine("商店發布優惠通知!");
Handles?.Invoke();
}
}
//具體訂閱者類中實現通知后處理的方法。
public class CustomerA
{
public void Handle()
{
Console.WriteLine("顧客A收到優惠通知。");
}
}
public class CustomerB
{
public void Handle()
{
Console.WriteLine("顧客B收到優惠通知。");
}
}
class Program
{
static void Main(string[] args)
{
var subject = new Subject();
var observerA = new CustomerA();
subject.Handles += observerA.Handle;
var observerB = new CustomerB();
subject.Handles += observerB.Handle;
subject.Publish();
Console.WriteLine();
subject.Handles -= observerB.Handle;
subject.Publish();
Console.ReadKey();
}
}
讓我們來看看輸出結果:
商店發布優惠通知!
顧客A收到優惠通知。
顧客B收到優惠通知。
商店發布優惠通知!
顧客A收到優惠通知。