设计模式-行为型-观察者模式

观察者模式



前言

观察者模式是为了将观察者和被观察者进行解耦,时被观察者在被改变时观察者可以及时的做出响应。例如:邮件通知,各种短信消息的订阅,扣费通知等等。


一、观察者模式(发布-订阅模式,事件订阅者)

是一种订阅机制,在对象事件发生时通知多个观察者。例如发布订阅中的订阅者,在消息被发布到指定位置后,订阅该位置的订阅者监听到消息,然后可以进行消息处理。

二、角色分析

  1. 抽象主题(ISubject):指被观察的对象,是一个抽象类或接口,定义了增删通知观察者对象的方法。
  2. 具体主题(ConcreteSubject):具体被观察者,当内部发生变化时,会通知已注册的观察者。
  3. 抽象观察者(IObserver):定义了相应通知的更新方法。
  4. 具体观察者(ConcreteObserver):当得到状态更新的通知时,会自动做出响应。

三、应用场景

  • 当一个抽象模型包含两方面内容,其中一方面依赖另一方面的紧耦合情况。
  • 一个对象的变化,将影响另外一个或多个对象的一系列变化。
  • 实现类似广播机制的功能,不需要知道具体的收听者,只需要分发广播,系统中感兴趣的对象会自动接收该广播。
  • 多层级嵌套使用,形成一种链式触发机制,是的事件具备跨域通知

四、代码实现

1.抽象观察者

代码如下(示例):抽象消息的处理方法

	/// <summary>
    /// 抽象观察者
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IObserver<T>
    {
        public void update(T t);
    }

2.抽象主题

代码如下(示例):抽象观察者的管理

	/// <summary>
    /// 抽象主题
    /// </summary>
    public interface ISubject<T>
    {
        ISubject<T> attach(IObserver<T> observer);
        bool detach(IObserver<T> observer);
        void notify(T t);
    }

3.具体观察者

代码如下(示例):对观测到的消息的处理

	/// <summary>
    /// 具体观察者
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ConcreteObserver<T> : IObserver<T>
    {
        /// <summary>
        /// 答应观察到的消息
        /// </summary>
        /// <param name="t"></param>
        public void update(T t)
        {
            Console.WriteLine("receive event:" + JsonConvert.SerializeObject(t));
        }
    }

4.具体主题

代码如下(示例):对订阅者的管理(注册,注销),以及消息的发布,

 	/// <summary>
    /// 具体主题
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ConcreteSubject<T> : ISubject<T>
    {
        private List<IObserver<T>> observers = new List<IObserver<T>>();        
        /// <summary>
        /// 绑定发布者和订阅者关系
        /// </summary>
        /// <param name="observer"></param>
        /// <returns></returns>
        public ISubject<T> attach(IObserver<T> observer)
        {

            if (!this.observers.Contains(observer))
            {
                Console.WriteLine($"将{JsonConvert.SerializeObject(observer)}添加到 List<IObserver<{typeof(T).Name}>>集合");
                this.observers.Add(observer);
                return this;
            }
            else
            {
                return this;
            }
        }
        /// <summary>
        /// 删除发布订阅关系
        /// </summary>
        /// <param name="observer"></param>
        /// <returns></returns>
        public bool detach(IObserver<T> observer)
        {
            return this.observers.Remove(observer);
        }
        /// <summary>
        /// 调用接收者消息
        /// </summary>
        /// <param name="t"></param>
        public void notify(T t)
        {
            for (var i = 0; i < observers.Count; i++) {
                Console.Write(i+"----------");
                observers[i].update(t);
            }
        }
    }

5.调用客户端

代码如下(示例):客户端创建观察者及被观察者,并绑定它们之间的关系,发布消息进行实现。

	/// <summary>
    /// 调用客户端
    /// </summary>
    public class Clienter {
        public void mains() {
            //创建被观察者
            ISubject<string> observable = new ConcreteSubject<string>();
            //实例化观察者
            IObserver<string> observer = new ConcreteObserver<string>();
            IObserver<string> observer1 = new ConcreteObserver<string>();
            //注册观察者
            observable
                .attach(observer)
                .attach(new ConcreteObserver<string>())
                .attach(new ConcreteObserver<string>())
                .attach(new ConcreteObserver<string>())
                .attach(new ConcreteObserver<string>())
                .attach(new ConcreteObserver<string>());
            //发布消息
            observable.notify("hello");
        }
    }

6.输出

{}添加到 List<IObserver<String>>集合
将{}添加到 List<IObserver<String>>集合
将{}添加到 List<IObserver<String>>集合
将{}添加到 List<IObserver<String>>集合
将{}添加到 List<IObserver<String>>集合
将{}添加到 List<IObserver<String>>集合
0----------receive event:"hello"
1----------receive event:"hello"
2----------receive event:"hello"
3----------receive event:"hello"
4----------receive event:"hello"
5----------receive event:"hello"

总结

优点

  • 观察者及被观察者是松散耦合的,复合依赖倒置原则。
  • 分离了观察者和被观察者,并建立了一套触发机制,使数据的变化可以影响到多个观察者。
  • 实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察者触发事件时,只有感兴趣的观察者会做出响应。

缺点

  • 如果观察者数量过多,则事件通知会耗时较长。
  • 事件通知称线性关系,如果其中一个观察者处理事件卡壳,则会影响后续的观察者接受该事件。
  • 如果观察者和被观察者之间存在循环依赖,则可以能造成两者之间的循环调用,导致系统崩溃。
  • 只能保持线性依赖,不能存在闭环依赖。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kenny@chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值