什么是觀察者模式


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收到優惠通知。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM