什么是观察者模式

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收到优惠通知。
posted @ 2021-01-10 11:00  南荣相如  阅读(861)  评论(0编辑  收藏  举报