[设计]观察者模式

来源:互联网 发布:用淘宝联盟赚钱安全吗 编辑:程序博客网 时间:2024/06/08 18:04

[设计]观察者模式

场景

  • 有很多客户端不定的会连接交互模块,也不知道何时退出,要实现连接上就进行消息推送,不连接就不推送。
    简单的办法找一个集合来记录所有的对象,如果来消息就扫一遍这个集合,然后执行对应的操作。

解决办法

  1. 能实现让这个记动权放在客户端手里吗?
  2. 能够依赖于抽象吗?每次观察者都能得到信息吗?
  3. c# 提供了委托和事件,你要这就是封好的模式,委托不就是一个抽象的观察者吗?
    • 我们先创建一个基于委托的观察者基类
namespace ObserverMode{    public delegate void NotifyEventHander(object sender);    class SubsciberBase    {        public NotifyEventHander NotifyEvnet;        public string Flag { get; set; }        public SubsciberBase(string str)        {            Flag = str;        }        public void AddObserver(NotifyEventHander neh)        {            NotifyEvnet += neh;        }        public void RemoveObserver(NotifyEventHander neh)        {            NotifyEvnet -= neh;        }        public void Update()        {            NotifyEvnet?.Invoke(this);        }    }}
  • 我们再创建一个观察者 这里我们不做操作,你需要什么你可以做什么
 class LidarSubscriber:SubsciberBase    {        public LidarSubscriber(string str):base(str)        {        }    }
  • 我们实例化一个客户端类也就是传说中的订阅者
 class LidarClient    {        public string Name { get; set; }        public LidarClient(string name)        {            Name = name;        }        public void ReceiveAndPrint(object obj)        {            SubsciberBase sb = obj as SubsciberBase;            if (null!=sb)            {                Console.WriteLine("{0},{1}",sb.Flag,Name);            }        }    }
  • 最后我们在用的时候确定订阅关系
static void Main(string[] args)        {            SubsciberBase Sb = new LidarSubscriber("Lidar");            LidarClient ld1 = new LidarClient("client1");            LidarClient ld2 = new LidarClient("client2");            LidarClient ld3 = new LidarClient("client3");            Sb.AddObserver(new NotifyEventHander(ld1.ReceiveAndPrint));            Sb.AddObserver(new NotifyEventHander(ld2.ReceiveAndPrint));            Sb.AddObserver(new NotifyEventHander(ld3.ReceiveAndPrint));            Sb.Update();            Console.WriteLine("*****************");            Sb.RemoveObserver(ld2.ReceiveAndPrint);            Sb.Update();            Console.Read();        }

类图

  • 占坑

注意

  1. 我们用了C#封好的接口所以方便了很多。
  2. 观察者的好处就是解耦,也就是说我要做一个事我不讲谁去做我只要最后的结果
  3. 一般在跨系统的时候用的较多,因为两者都依赖于抽象谁都不用理谁。但是最后交互关系在这就足够了,也就是传说的中主在矛盾。
  4. 事件注意C#中的弱事件
    源码
    原文网址

发现好技术好文章是一切的第一步,这里不适用万事开头难,在编程这个世界里最简单的就是第一步,如果你感觉到难,那说明最后的几步可能更难,相对中间容易点。哈哈,坚持吧。

原创粉丝点击