zoukankan      html  css  js  c++  java
  • c#设计模式系列:观察者模式(Observer Pattern)

    引言

    在现实生活中,处处可见观察者模式,例如,微信中的订阅号,订阅博客和QQ微博中关注好友,这些都属于观察者模式的应用。在这一章将分享我对观察者模式的理解,废话不多说了,直接进入今天的主题。

    观察者模式的介绍

    2.1 观察者模式的定义

       从生活中的例子可以看出,只要对订阅号进行关注的客户端,如果订阅号有什么更新,就会直接推送给订阅了的用户。从中,我们就可以得出观察者模式的定义。

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

    2.2 观察者模式的结构图

    1048776-20171130133356354-676034245

    可以看出,在观察者模式的结构图有以下角色:

    • 抽象主题角色(Subject):抽象主题把所有观察者对象的引用保存在一个列表中,并提供增加和删除观察者对象的操作,抽象主题角色又叫做抽象被观察者角色,一般由抽象类或接口实现。
    • 抽象观察者角色(Observer):为所有具体观察者定义一个接口,在得到主题通知时更新自己,一般由抽象类或接口实现。
    • 具体主题角色(ConcreteSubject):实现抽象主题接口,具体主题角色又叫做具体被观察者角色。
    • 具体观察者角色(ConcreteObserver):实现抽象观察者角色所要求的接口,以便使自身状态与主题的状态相协调。

    2.3观察者模式的实现

    下面我们已抖音为例,当你刷抖音时候,看到一个很不错的小视频,就关注了这个作者,以后作者每次更新视频的时候,系统都会给关注他的粉丝推送新的消息,下面是我写的第一版实现代码:

      /// <summary>
        /// 作者
        /// </summary>
        public class OAuth
        {
            private List<Fans> list = new List<Fans>();
            public string name { get; set; }
    
            /// <summary>
            /// 新增一个粉丝
            /// </summary>
            /// <param name="add"></param>
            public void Add(Fans add)
            {
                list.Add(add);
            }
            /// <summary>
            /// 减少一个粉丝
            /// </summary>
            /// <param name="remove"></param>
            public void Remove(Fans remove)
            {
                list.Remove(remove);
            }
            public void Nofify()
            {
                foreach (Fans item in list)
                {
                    item.Update();
                }
            }
        }
        /// <summary>
        /// 粉丝
        /// </summary>
        public class Fans
        {
    
            private string name;
            private OAuth sub;
            public Fans(string name, OAuth sub)
            {
                this.name = name;
                this.sub = sub;
            }
            public void Update()
            {
                Console.WriteLine("你好:{0},{1}发布了新的作品,点击查看",name,sub.name);
            }
        }
    
       /// <summary>
        /// 客户端
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
    
                OAuth oauth = new OAuth();
                oauth.name = "小炒肉";
                Fans a = new Fans("青椒",oauth);
                Fans b = new Fans("胡萝卜",oauth);
                oauth.Add(a);
                oauth.Add(b);
    
                oauth.Nofify();
    
                Console.ReadLine();
            }
        }
        //结果显示
        你好:青椒,小炒肉发布了新的作品,点击查看
        你好:胡萝卜,小炒肉发布了新的作品,点击查看
    
    View Code

    看到这种代码我们首先想到的是 违反了面向对象的开发-封闭原则,其次是依赖倒转原则,类与类之间不应该相互依赖,而应该依赖与抽象,好了,我们得重新修改了,10分钟后第二版出来了

       public abstract  class Observer
        {
            protected string name;
            protected Subject sub;
            public Observer(string name, Subject sub)
            {
                this.name = name;
                this.sub = sub;
            }
            public abstract void Update();
        }
    
        public class Person : Observer
        {
            public Person(string name, Subject sub) : base(name, sub) { }
    
            public override void Update()
            {
                Console.WriteLine("你好:{0},{1}发布了新的作品,点击查看", name, sub.name);
            }
        }
     public abstract class Subject
        {
            public string name { get; set; }
            public abstract void Add(Observer ob);
            public abstract void Remove(Observer ob);
            public abstract void Notify();
        }
        public class Green : Subject
        {
            private List<Observer> list = new List<Observer>();
            public override void Add(Observer ob)
            {
                list.Add(ob);
            }
            public override void Notify()
            {
                foreach (var item in list)
                {
                    item.Update();
                }
            }
            public override void Remove(Observer ob)
            {
                list.Remove(ob);
            }
        }
        /// <summary>
        /// 客户端
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                Subject ob = new Green();
                ob.name = "小炒肉";
                Observer a = new Person("青椒", ob);
                Observer b = new Person("胡萝卜", ob);
                ob.Add(a);
                ob.Add(b);
                ob.Notify();
                Console.ReadLine();
            }
        }
      ///结果
    你好:青椒,小炒肉发布了新的作品,点击查看
    你好:胡萝卜,小炒肉发布了新的作品,点击查看
    View Code

      现在已经依赖接口编程,但是“抽象通知者”还是依赖 抽象观察者,也就是说,万一没有了抽象观察者这样的接口,我这通知的功能就完成不了,下面我们引入委托解耦实现通知者和观察者

        public class Person
        {
            protected string name;
            protected Subject sub;
            public Person(string name, Subject sub)
            {
                this.name = name;
                this.sub = sub;
            }
            public  void UpdateTP()
            {
                Console.WriteLine("你好:{0},{1}发布了新的作品,点击查看", name, sub.name);
            }
        }
        public delegate void EventHandler();
       public interface Subject
        {
            string name { get; set; }
             void Notify();
        }
        public class Green : Subject
        {
    
            public event EventHandler Update;
            public string name { get; set; }
    
            public void Notify()
            {
                Update();
            }
        }
        /// <summary>
        /// 客户端
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                Green hand = new Green();
                hand.name = "小王";
                Person per = new Person("青椒",hand);
                Person Ge = new Person("小炒肉", hand);
                hand.Update += new EventHandler(per.UpdateTP);
                hand.Update += new EventHandler(Ge.UpdateTP);
    
                hand.Notify();
    
                Console.ReadLine();
            }
        }
    View Code

    总结

    在C#的event中,委托充当了抽象的Observer接口,而提供事件的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计。

    好了在次复习下,观察者模式的定义,观察者模式定义了一种一对多的关系,让多个观察者对象可以同时监听某一个主题对象,这个主题对象在发送状态改变时,会通知所有观察者对象,时它们能够自动更新自己

  • 相关阅读:
    Web应用指纹识别
    同步I/O 和 异步I/O
    怎样找出自己定义标签的java类
    Android多线程文件下载器
    cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&amp;同一时候带着刚体
    记C++课程设计--学生信息管理系统
    iOS开发--从TQRichTextViewDemo中学会分析project
    九度oj题目&amp;吉大考研10年机试题全解
    setOnFocusChangeListener的使用
    查看网络port占用
  • 原文地址:https://www.cnblogs.com/studydp/p/9556861.html
Copyright © 2011-2022 走看看