为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
设计模式

🎏 序言

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

🎏 01.观察者模式的解释

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

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

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

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

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

https://img1.sycdn.imooc.com//6121288e00017f5c09760371.jpg

图中可以看出,被观察者是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();



作者:webmote33
链接:https://juejin.cn/post/6998909471766347784
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消