设计模式之观察者模式

观察者模式定义#

观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。也就是我们常说的发布-订阅。

观察者模式结构#

image-20210713212802376

观察者模式实现#

声明抽象观察者(订阅者),也可以是接口

public abstract class Observer
    {
        public abstract void Update();
    }

创建具体观察者,使其继承自抽象观察者

public class ConcertSubject : Subject
    {
        private string _state;
        /// <summary>
        /// 具体被观察者状态
        /// </summary>
        public string State
        {
            get { return _state; }
            set { _state = value; }
        }

    }

创建抽象发布者

public abstract class Subject
    {
        private List<Observer> observers = new List<Observer>();

        ...

        /// <summary>
        /// 通知
        /// </summary>
        public void Notify()
        {
            foreach (var item in observers)
            {
                item.Update();
            }
        }
    }

创建具体发布者,继承自抽象发布者

public class ConcertSubject : Subject
    {
        private string _state;
        /// <summary>
        /// 具体被观察者状态
        /// </summary>
        public string State
        {
            get { return _state; }
            set { _state = value; }
        }

    }

客户端代码

ConcertSubject sub = new ConcertSubject();

            sub.Addach(new ConcertObserver(sub, "1"));
            sub.Addach(new ConcertObserver(sub, "2"));
            sub.Addach(new ConcertObserver(sub, "3"));

            sub.State = "online";
            sub.Notify();

可以结合委托事件实现,具体代码参考仓库代码示例

观察者模式优缺点#

优点#

  • 开闭原则。 无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类)。
  • 可以在运行时建立对象之间的联系。

缺点#

  • 订阅者的通知顺序是随机的

观察者模式使用场景#

  • 当一个对象状态的改变需要改变其他对象,或实际对象是事先未知的或动态变化的时,可使用观察者模式。
    1. 当你使用图形用户界面类时通常会遇到一个问题。 比如, 你创建了自定义按钮类并允许客户端在按钮中注入自定义代码, 这样当用户按下按钮时就会触发这些代码。
    2. 观察者模式允许任何实现了订阅者接口的对象订阅发布者对象的事件通知。 你可在按钮中添加订阅机制, 允许客户端通过自定义订阅类注入自定义代码。
  • 当应用中的一些对象必须观察其他对象时, 可使用该模式。但仅能在有限时间内或特定情况下使用。
    1. 订阅列表是动态的, 因此订阅者可随时加入或离开该列表。

示例源代码#

源代码仓库地址:https://github.com/luchong0813/DesignModel

作者:傲慢与偏见

出处:https://www.cnblogs.com/chonglu/p/15008592.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

声明:如果本文对您有帮助,请点击【推荐】您的赞赏将鼓励我继续创作!想跟我一起进步么?那就【关注】我吧

posted @   傲慢与偏见luc  阅读(79)  评论(1编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示