【设计模式】观察者模式

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

特点:
优点:

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

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

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

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

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

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

适用场景:

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

· 数据变化通知;

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

举例场景:

· 游戏中血条的变化;

· 股票价格的涨跌通知;

· 按钮点击的响应;

相关推荐
_哆啦A梦18 小时前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
Scout-leaf2 天前
WPF新手村教程(三)—— 路由事件
c#·wpf
用户298698530142 天前
程序员效率工具:Spire.Doc如何助你一键搞定Word表格排版
后端·c#·.net
mudtools3 天前
搭建一套.net下能落地的飞书考勤系统
后端·c#·.net
玩泥巴的3 天前
搭建一套.net下能落地的飞书考勤系统
c#·.net·二次开发·飞书
唐宋元明清21884 天前
.NET 本地Db数据库-技术方案选型
windows·c#
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
lindexi4 天前
dotnet DirectX 通过可等待交换链降低输入渲染延迟
c#·directx·d2d·direct2d·vortice
feifeigo1234 天前
matlab画图工具
开发语言·matlab
dustcell.4 天前
haproxy七层代理
java·开发语言·前端