【设计模式】观察者模式

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

特点:
优点:

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

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

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

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

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

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

适用场景:

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

· 数据变化通知;

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

举例场景:

· 游戏中血条的变化;

· 股票价格的涨跌通知;

· 按钮点击的响应;

相关推荐
c#上位机3 小时前
halcon计算区域骨架
图像处理·人工智能·计算机视觉·c#·halcon
你不是我我3 小时前
【Java 开发日记】我们来说一说 Redis IO 多路复用模型
java·开发语言·redis
想七想八不如114083 小时前
408操作系统 PV专题
开发语言·算法
浩瀚地学3 小时前
【Java】ArrayList
java·开发语言·经验分享·笔记
阿杰同学3 小时前
Java 设计模式 面试题及答案整理,最新面试题
java·开发语言·设计模式
这样の我3 小时前
java 模拟chrome指纹 处理tls extension顺序
java·开发语言·chrome
yong99903 小时前
基于MATLAB的雷达压制干扰仿真
开发语言·matlab
catchadmin4 小时前
现代高效 PHP 开发的最佳实践
开发语言·后端·php
AnAnCode4 小时前
【时间轮算法-实战】Java基于Netty的 `HashedWheelTimer`快速搭建时间轮算法系统
java·开发语言·算法·时间轮算法