C# 基于事件的观察者模式

观察者模式是一种软件设计模式,用于定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,它的所有依赖者(观察者)都将得到通知并自动更新。这种模式通过解耦合主题和观察者来提高对象的灵活性。

定义

观察者模式包括一个主题(Subject)和多个观察者(Observer)。当主题的状态改变时,它会通知观察者并调用它们的特定方法,使得观察者可以自动更新。

应用场景

观察者模式常见于以下场景:

  1. 当一个对象的变化需要通知其他对象,而且你无法确切知道有多少个对象需要通知时,可以使用观察者模式。

  2. 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,这时使用观察者模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。

优点

  1. 观察者模式降低了主题和观察者之间的耦合度,使得主题和观察者可以轻松地独立变化。

  2. 支持广播通信,观察者模式可以向多个对象同时发送通知。

缺点

  1. 如果观察者过多或通知机制过于复杂,容易导致性能问题。

  2. 如果观察者和主题之间存在循环依赖,可能会导致系统崩溃或出现死循环。

观察者模式是一种广泛应用的设计模式,在许多面向对象编程语言和框架中都有相应的实现,例如在事件处理、模型-视图-控制器 (MVC) 架构中都有观察者模式的影子。

Demo

1.Subject类

cs 复制代码
internal abstract class SubjectBase
    {
        // 将所有观察者放入list集合
        private readonly List<Observer> observers = new List<Observer>();
        public event EventHandler<EventArgs> NotifyAllHandler;
        public virtual void NotifyAllObserver()
        {
            NotifyAllHandler?.Invoke(this, EventArgs.Empty);
        }
        /// <summary>
        /// 加入集合
        /// </summary>
        /// <param name="observer"></param>
        public virtual void AttachObserver(Observer observer)
        {
            observers.Add(observer);
        }
        /// <summary>
        /// 从观察者列表中去除
        /// </summary>
        /// <param name="observer"></param>
        public virtual void RemoveObserver(Observer observer)
        {
            observers.Remove(observer);
        }
    }
internal class Subject: SubjectBase
    {
       
    }

2.Observer观察者抽象类

cs 复制代码
    /// <summary>
    /// 观察者抽象类
    /// </summary>
    internal abstract class Observer
    {
        protected SubjectBase _subject;
        /// <summary>
        /// 更新消息
        /// </summary>
        public abstract void Update(object? sender, EventArgs eventArgs);
        public virtual void SetSubject(SubjectBase subject)
        {
            if (subject == _subject) return;
            if (this._subject != null)
            {
                this._subject.RemoveObserver(this);
                this._subject.NotifyAllHandler -= Update;
            }
            this._subject = subject;
            this._subject.AttachObserver(this);
            this._subject.NotifyAllHandler += Update;
        }
    }

3.具体观察者,需要继承Observer基类

cs 复制代码
internal class Observer_A : Observer
    {
        public override void Update(object? sender, EventArgs eventArgs)
        {
            Console.WriteLine($"Observer_A");
        }
    }

internal class Observer_B : Observer
    {
        public override void Update(object? sender, EventArgs eventArgs)
        {
            Console.WriteLine($"Observer_B");
        }
    }

调用

cs 复制代码
// 发布类
SubjectBase subject = new Subject();

// 观察者
Observer observerA = new Observer_A();
observerA.SetSubject(subject);
Observer observerB = new Observer_B();
observerB.SetSubject(subject);

// 发布类间隔通知
await Task.Run(() =>
{
    while (true)
    {
        subject.NotifyAllObserver();
        Console.WriteLine("====================================================");
        Thread.Sleep(3000);
    }
});
相关推荐
西岭千秋雪_6 小时前
设计模式の中介者&发布订阅&备忘录模式
java·观察者模式·设计模式·中介者模式·备忘录模式
东风吹柳3 天前
观察者模式(sigslot in C++)
c++·观察者模式·信号槽·sigslot
T1an-13 天前
设计模式之【观察者模式】
观察者模式·设计模式
真想骂*7 天前
观察者模式:它究竟在观察什么?
java·开发语言·观察者模式
夏旭泽7 天前
设计模式-观察者模式
观察者模式·设计模式
澄澈i8 天前
设计模式学习[12]---观察者模式
学习·观察者模式·设计模式
问道飞鱼11 天前
【设计模式】观察者模式深度讲解
观察者模式·设计模式
吾与谁归in12 天前
【C#设计模式(20)——观察者模式(Observer Pattern)】
观察者模式·设计模式·c#
你又食言了哦18 天前
C++观察者模式Observer
开发语言·c++·观察者模式
ohMyGod_12319 天前
手写观察者模式
观察者模式