.Net设计模式进阶之路——观察者模式(Observer)

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创,首发于 【掘金】
  • 📢作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!💪💪💪

🎏 序言

观察者模式,又叫发布-订阅模式(Publish/Subscribe),既然有观察者,当然也有被观察者,就如同在你的生活中,有一双明亮的眼睛时刻注视着你,你发生的大大小小的事情,它都了如指掌。

🎏 01.观察者模式的解释

意图: 定义对象间的一种一对多的依赖关系 ,当一个对象的状态发生改变时 , 所有依赖于它的对象 都得到通知并被自动更新。

问题领域: 它一般用来解决下列问题。

  • 观察者和被观察者需要解耦,或者有多个观察者

  • 需要把自己的状态通知给其他对象

解决方案: 我们使用UML图来描述它。

image.png

图中可以看出,被观察者是Subject,其可以有很多观察者Observer,被观察者发布通知,观察者收到通知。

效果:

  • 好处:
  1. 一个对象状态改变,可以通知所有的观察者;
  2. 观察者和被观察者只有抽象层耦合;
  3. 有一套触发机制
  • 限定:
  1. 通知所有的观察者,在观察者多的时候会花费很多时间
  2. 观察者和被观察者间有循环依赖,可能导致系统崩溃

🎏 02. dotnet core 源码赏析

 internal interface ICascadingValueComponent
    {
        // This interface exists only so that CascadingParameterState has a way
        // to work with all CascadingValue<T> types regardless of T.

        bool CanSupplyValue(Type valueType, string? valueName);

        object? CurrentValue { get; }

        bool CurrentValueIsFixed { get; }

        void Subscribe(ComponentState subscriber);

        void Unsubscribe(ComponentState subscriber);
    }
    
    //实现类
     void ICascadingValueComponent.Unsubscribe(ComponentState subscriber)
        {
            _subscribers?.Remove(subscriber);
        }

        private void NotifySubscribers(in ParameterViewLifetime lifetime)
        {
            foreach (var subscriber in _subscribers!)
            {
                subscriber.NotifyCascadingValueChanged(lifetime);
            }
        }
复制代码

发布订阅还是蛮常见的,在asp.net core代码中可以查看到很多类似的用法。

🎏 03. dotnet 生成器实现

构建一个抽象的观察者,并实现几个实例。

实例观察者实现,可以加到被观察者的观察列表。

public abstract class Visitor
    {
        public abstract void VisitConcreteElementA(
            ConcreteElementA concreteElementA);
        public abstract void VisitConcreteElementB(
            ConcreteElementB concreteElementB);
    }
    /// <summary>
    /// A 'ConcreteVisitor' class
    /// </summary>
    public class ConcreteVisitor1 : Visitor
    {
        public override void VisitConcreteElementA(
            ConcreteElementA concreteElementA)
        {
            Console.WriteLine("{0} visited by {1}",
                concreteElementA.GetType().Name, this.GetType().Name);
        }
        public override void VisitConcreteElementB(
            ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0} visited by {1}",
                concreteElementB.GetType().Name, this.GetType().Name);
        }
    } 
复制代码

调用方,可以按照实例类型调用直接使用。

ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
// Create visitor objects
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
// Structure accepting visitors
o.Accept(v1);
o.Accept(v2);
// Wait for user
Console.ReadKey();
复制代码

🎏 04. 小结

30天不停更,目标很远大,今天是第二天,加油吧,兄弟们!

例行小结,理性看待!

结的是啥啊,结的是我想你点赞而不可得的寂寞。😳😳😳

👓都看到这了,还在乎点个赞吗?

👓都点赞了,还在乎一个收藏吗?

👓都收藏了,还在乎一个评论吗?