zoukankan      html  css  js  c++  java
  • c#设计模式(3)—— 利用观察者模式模拟推送消息

    1、观察者模式概念

      观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己的行为。

      观察者模式实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层,即观察者。

      观察者模式在被观察者和观察者之间建立了一个抽象的耦合,被观察者并不知道任何一个具体的观察者,只是保存着抽象观察者的列表,每个具体观察者都符合一个抽象观察者的接口。

    2、业务场景

      模拟管理系统推送最新讯息给对应用户,采用观察者模式将很好的模拟此类场景,使发布者与订阅者之间实现解耦。

    3、实战

    3.1 定义实体对象

    定义订阅者实体类

    namespace SubscriberDesignWithRedis.Model
    {
        public class User
        {
            /// <summary>
            /// 用户id
            /// </summary>
            public string userId { get; set; }
            /// <summary>
            /// 用户名称
            /// </summary>
            public string userName { get; set; }
        }
    }

    此处List<User> 用于存储订阅者列表

    namespace SubscriberDesignWithRedis.Model
    {
        [Serializable]
        public class Information
        {
            /// <summary>
            /// 发布者集合
            /// </summary>
            public List<User> userList{ get; set; }
            /// <summary>
            /// 信号
            /// </summary>
            public string signal { get; set; }
            /// <summary>
            /// 消息
            /// </summary>
            public string info { get; set; }
        }
    }

    3.2 发布者

        /// <summary>
        /// 门户发布信息
        /// </summary>
        public class PortalPublish
        {
            /// <summary>
            /// 定义委托方法,充当订阅者接口
            /// </summary>
            /// <param name="obj"></param>
            public delegate void NotifySubscribeEventHandler(object obj);
    
            /// <summary>
            /// 发布消息内部类
            /// </summary>
            public class PublishInfo
            {
                public NotifySubscribeEventHandler notifyEvent;
                /// <summary>
                /// 消息实体
                /// </summary>
                public Information Information { get; set; }
                /// <summary>
                /// 重载构造器
                /// </summary>
                /// <param name="information">消息实体</param>
                public PublishInfo(Information information)
                {
                    this.Information = information;
                }
                /// <summary>
                /// 新增
                /// </summary>
                /// <param name="ob"></param>
                public void AddSubscribe(NotifySubscribeEventHandler ob){
                    notifyEvent += ob;
                }
                /// <summary>
                /// 删除
                /// </summary>
                /// <param name="ob"></param>
                public void RemoveSubscribe(NotifySubscribeEventHandler ob){
                    notifyEvent -= ob;
                }
                /// <summary>
                /// 更新( 使用lamda表达式 )
                /// </summary>
                public void Update() => notifyEvent?.Invoke(this);
            }
            public class PortalPublishInfo : PublishInfo
            {
                public PortalPublishInfo(Information information) : base(information) { }
            }
        }

    3.3 订阅者

    namespace SubscriberDesignWithRedis
    {
        public class Subscriber
        {
            public string Name { get; set; }
            public Subscriber(string name)
            {
                this.Name = name;
            }
            /// <summary>
            /// 接收
            /// </summary>
            /// <param name="obj"></param>
            public void Recevie(object obj)
            {
                PortalPublish.PortalPublishInfo portalPublishInfo = obj as PortalPublish.PortalPublishInfo;
                if(portalPublishInfo != null)
                {
                    Console.WriteLine("Notified {0} of {1}'s " + "Info is :{2}", Name, 
                portalPublishInfo.Information.signal, portalPublishInfo.Information.info); } } } }

    3.4 测试类

    namespace SubscriberDesignWithRedis
    {
        class Program
        {
            static void Main(string[] args)
            {
                //模拟订阅者的集合
                List<User> userList = new List<User>() {
                    new User() { userId = "1", userName = "ozil" },
                    new User() { userId = "2",userName = "Alexis"}
                };
                //定义发布数据
                Information information = new Information() {
                    signal = "Publish Info",
                    info = "this is a new information for each client",
                    userList = userList
                };
                PortalPublishInfo portalPublish = new PortalPublishInfo(information);
                Console.WriteLine("添加订阅者");
                //循环订阅者列表,将消息发送给具体订阅者
                foreach (User user in userList)
                {
                    Subscriber client = new Subscriber(user.userName);
                    portalPublish.AddSubscribe(new NotifySubscribeEventHandler(client.Recevie));
                }
                //执行事件
                portalPublish.Update();
                Console.WriteLine("--------------------------------------------");
    
                Console.WriteLine("移除订阅者");
                foreach (User user in userList)
                {
                    Subscriber client = new Subscriber(user.userName);
                    portalPublish.RemoveSubscribe(new NotifySubscribeEventHandler(client.Recevie));
                }
                //执行事件
                portalPublish.Update();
                Console.ReadLine();
            }
        }
    }

    4、运行结果

  • 相关阅读:
    Android组件化和插件化开发
    开发一流的 Android SDK:Fabric SDK 的创建经验
    关系 和非关系 阻塞非阻塞的区别
    AJAX 中JSON 和JSONP 的区别 以及请求原理
    九马画山数命运, 一身伴君不羡仙! 与代码不离不弃!
    移动端 transitionEnd函数用来检测过渡是否完成
    2017前端该学的知识 分享墨白的文章、大家共勉!
    移动端和pc端事件绑定方式以及取消浏览器默认样式和取消冒泡
    今天要带来的是移动端开发的基础内容
    离线存储
  • 原文地址:https://www.cnblogs.com/cklovefan/p/7875476.html
Copyright © 2011-2022 走看看