【设计模式】观察者模式

观察者模式(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();
    }
}

特点:
优点:

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

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

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

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

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

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

适用场景:

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

· 数据变化通知;

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

举例场景:

· 游戏中血条的变化;

· 股票价格的涨跌通知;

· 按钮点击的响应;

相关推荐
死磕音视频10 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
顽疲12 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog13 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
曹牧13 小时前
C#:输入的字符串格式不正确
c#
程序喵大人14 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)15 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
博风15 小时前
8、设计模式应用举例:适配器模式:Iterator接口与Enumeration接口
设计模式·适配器模式
学逆向的15 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质16 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
高晶16 小时前
ARM 嵌入式 Linux 系统 U-Boot 开发与移植实战M
设计模式·程序员