【设计模式】观察者模式

观察者模式(Observer Pattern)

概念:

· 一种行为型设计模式;

· 用于对象间的一对多依赖;

· 适合解耦发布者和订阅者;

UML结构:

复制代码
          ┌───────────┐
          │  Subject  │
          ├───────────┤
          │+ Attach() │
          │+ Detach() │
          │+ Notify() │
          └───────────┘
                ▲
                │
      ┌─────────┴─────────┐
      │                   │
┌─────────────┐     ┌─────────────┐
│ConcreteSubject│     │  Observer   │
└─────────────┘     ├─────────────┤
│- state       │     │+ Update()   │
│+ GetState()  │     └─────────────┘
│+ SetState()  │
└─────────────┘
      ▲
      │
┌─────────────┐
│ConcreteObserver│
└─────────────┘
│- name        │
│+ Update()    │
└─────────────┘

代码示例:

cs 复制代码
/// <summary>
/// 抽象观察者接口
/// </summary>
public interface IObserver
{
    void Receive();
}

/// <summary>
/// 实际的观察者类
/// </summary>
public class ConcreteObserver : IObserver
{
    public string Name { get; set; }

    public void Receive()
    {
        Console.WriteLine($"监听者:{Name},接收到信号");
    }
}

/// <summary>
/// 上下文(也叫被观察者类)
/// </summary>
public class Context
{
    private readonly List<IObserver> listeners = new();

    public void AddListener(IObserver observer)
    {
        if (observer != null && !listeners.Contains(observer))
        {
            listeners.Add(observer);
        }
    }

    public void RemoveListener(IObserver observer)
    {
        listeners.Remove(observer);
    }

    /// <summary>
    /// 通知所管理的观察者
    /// </summary>
    public void Notify()
    {   
        // 使用for循环,避免在遍历时有观察者被移除而发生异常
        for (int i = 0; i < listeners.Count; i++)
        {
            listeners[i].Receive();
        }
    }
}

/// <summary>
/// 客户端
/// </summary>
public class Client
{
    public static void Main()
    {
        IObserver observerA = new ConcreteObserver();
        IObserver observerB = new ConcreteObserver();

        Context context = new Context();

        context.AddListener(observerA);
        context.AddListener(observerB);

        context.Notify();
    }
}

特点:
优点:

· 实现对象之间的松耦合:主题和观察者不直接依赖具体实现;

· 支持广播通信:一个主题可以通知多个观察者;

· 动态灵活:可以随时增加或减少观察者;
缺点:

· 观察者过多会导致性能下降;

· 需要注意对观察者的管理;

· 若观察者之间也需要相互观察,可能会导致无限的循环;

适用场景:

· 事件驱动系统:点击一个按钮,通知其他组件;

· 数据变化通知;

· 消息订阅机制:消息队列、广播系统、游戏状态的更新;

举例场景:

· 游戏中血条的变化;

· 股票价格的涨跌通知;

· 按钮点击的响应;

相关推荐
点心的游戏开发世界13 小时前
Unity C# 脚本学习笔记:命名空间与 using
学习·unity·c#
2601_9620715714 小时前
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
java·开发语言
淡海水15 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
点心的游戏开发世界15 小时前
Unity C# 脚本学习笔记:泛型
学习·unity·c#
CS_Zero15 小时前
C语言sizeof是函数吗?
c语言·开发语言
-今昭-16 小时前
《V2V 迁移实战:将 VMware 虚拟机转为 OpenStack 可用 Glance qcow2 镜像》
开发语言·python
黑马程序员毕设18 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设
_Twink1e19 小时前
openJiuwen 实训营 Day 1 · WorkSwarm 入门教程
开发语言·c++·openjiuwen
公子小六19 小时前
基于.NET的Windows窗体编程之WinForms滑块与上下控件
windows·microsoft·c#·.net·winforms
问天_观心19 小时前
大模型微调学习(一)
开发语言·人工智能·学习·语言模型·github