c#设计模式-行为型模式 之 观察者模式

定义:

又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者 对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自 动更新自己。

在观察者模式中有如下角色:

  1. Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每 个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  2. ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具 体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  3. Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知 时更新自己。
  4. ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知 时更新自身的状态。

案例

这里案例使用一个委托进行多播来进行对热水器的观察

加热器类

首先定义一个全局变量,温度temperature,然后使用event声明一个事件,委托名称使用无返回值的Action,参数为int。然后写一个for循环模拟烧水,温度temperature大于95时,执行事件。

cs 复制代码
public class HeaterSubject
{
    private int _temperature;

    public event Action<int> OnBoilEvent;

    public void BoilWater()
    {
        for (int i = 0; i < 100; i++)
        {
            _temperature++;
            
            if (_temperature >= 95)
            {
                OnBoilEvent.Invoke(_temperature);//触发事件:发出警报,显示水温
            }
        }
    }
}

监视者

热水器上一般都有显示屏和警报器,这里模拟两个观察者,分别是显示器和警报器

因为上面声明的委托参数是int,这里的观察者参数也要匹配,等一下才可以通过多播的形式插入

cs 复制代码
public class DisPlayObserver
{
    /// <summary>
    /// 显示水温
    /// </summary>
    /// <param name="temperature"></param>
    public void Display(int temperature)
    {
        Console.WriteLine($"显示屏-当前温度是:{temperature}");
    }
}
cs 复制代码
public class AlertObserver
{
    /// <summary>
    /// 发出警报
    /// </summary>
    /// <param name="temperature"></param>
    public void MakeAlert(int temperature)
    {
        Console.WriteLine($"语音报警器-温度是{temperature}");
    }
}

main方法

在main方法中,实现new一个热水器的实例,然后使用多播将多个方法绑定到一个委托实例。当调用此类委托时,所有绑定的方法会被一次全部调用,最后调用热水器的烧水方法

cs 复制代码
    public static void Main(string[] args)
    {
        HeaterSubject subject = new HeaterSubject();
        //订阅发出警报
        subject.OnBoilEvent += new AlertObserver().MakeAlert;
        //订阅显示水温
        subject.OnBoilEvent += new DisPlayObserver().Display;
        
        subject.BoilWater();
    }

多播的优缺点

  1. 优点: 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。 被观察者发送通知,所有注册的观察者都会收到信息【可以实现广播机制】
  2. 缺点: 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃

使用场景

  1. 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  2. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时。
相关推荐
一条闲鱼_mytube2 小时前
智能体设计模式(三)多智能体协作-记忆管理-学习与适应
人工智能·学习·设计模式
小屁猪qAq8 小时前
设计模式总纲
开发语言·c++·设计模式
小简GoGo9 小时前
前端常用设计模式快速入门
javascript·设计模式
会员果汁12 小时前
17.设计模式-单例模式(Singleton)
单例模式·设计模式
派大鑫wink12 小时前
【Day37】MVC 设计模式:原理与手动实现简易 MVC 框架
java·设计模式·mvc
会员果汁13 小时前
18.设计模式-桥接模式
设计模式·桥接模式
老蒋每日coding13 小时前
AI Agent 设计模式系列(九)——学习和适应模式
人工智能·学习·设计模式
da_vinci_x1 天前
武器设计实战:一把大剑裂变 5 种属性?Structure Ref 的“换肤”魔法
游戏·3d·设计模式·ai作画·aigc·设计师·游戏美术
刀法孜然1 天前
23种设计模式 3 行为型模式 之3.7 command 命令模式
设计模式·命令模式
一条闲鱼_mytube1 天前
智能体设计模式(二)反思-工具使用-规划
网络·人工智能·设计模式