菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
67
0

什么是观察者模式

原创
05/13 14:22
阅读数 29851

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

发表评论

0/200
67 点赞
0 评论
收藏