• C#设计模式--观察者模式(发布-订阅模式)


    0.C#设计模式--简单工厂模式

    1.C#设计模式--工厂方法模式

    2.C#设计模式--抽象工厂模式

    3.C#设计模式--单例模式

    4.C#设计模式--建造者模式

    5.C#设计模式--原型模式

    6.C#设计模式--设配器模式

    7.C#设计模式--装饰器模式

    8.C#设计模式--代理模式

    9.C#设计模式--外观模式

    10.C#设计模式--桥接模式

    设计模式:

    观察者模式(Observer Pattern)

    简单介绍:

      观察者模式(Observer Pattern)是设计模式中行为模式的一种,它解决了上述具有一对多依赖关系的对象的重用问题。此模式的参与者分为两大类,一类是被观察的目标,另一类是观察该目标的观察者们。正因为该模式是基于“一对多”的关系,所以该模式一般是应用于由一个目标对象和N个观察者对象组成(当然也可以扩展为有多个目标对象,但我们现在只讨论前者)的场合。当目标对象的状态发生改变或做出某种行为时,正在观察该目标对象的观察者们将自动地、连锁地作出相应的响应行为。

    模式中具有的角色

    1. 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
    2. 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
    3. 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
    4. 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

    举例子:博客的例子就是一个观察者模式,比如你关注一些作者的博客,当作者有博客发布时候,你就会收到一条该作者发布的博客的消息。

    抽象主题:Blog 博客

    具体主题:MyBlog   的博客

    抽象观察者:IObserver  

    具体的观察者:Observer

    观察者模式类图:

    观察者模式C#代码举例

    订阅博客抽象类

     1 /*****************************************************
     2  * ProjectName:  _11DesignPattern_Observer
     3  * Description:
     4  * ClassName:    Blog
     5  * CLRVersion:   4.0.30319.18408
     6  * Author:       JiYF
     7  * NameSpace:    _11DesignPattern_Observer
     8  * MachineName:  JIYONGFEI
     9  * CreateTime:   2017/5/23 17:08:10
    10  * UpdatedTime:  2017/5/23 17:08:10
    11 *****************************************************/
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Linq;
    15 using System.Text;
    16 
    17 namespace _11DesignPattern_Observer
    18 {
    19     /// <summary>
    20     /// 订阅博客抽象类
    21     /// </summary>
    22     public abstract class Blog
    23     {
    24         /// <summary>
    25         /// 保存订阅者列表
    26         /// </summary>
    27         private List<IObserver> observers = new List<IObserver>();
    28 
    29         /// <summary>
    30         /// 博主名
    31         /// </summary>
    32         public string BlogName { get; set; }
    33 
    34         /// <summary>
    35         /// 博客标题
    36         /// </summary>
    37         public string BlogTitle { get; set; } 
    38 
    39         /// <summary>
    40         /// 博客信息
    41         /// </summary>
    42         public string BlogInfo { get; set; }
    43 
    44         /// <summary>
    45         /// 博客构造函数
    46         /// </summary>
    47         /// <param name="blogTitle">博客标题</param>
    48         /// <param name="blogInfo">博客信息</param>
    49         public Blog(string name,string blogTitle,string blogInfo)
    50         {
    51             this.BlogName = name;
    52             this.BlogTitle = blogTitle;
    53             this.BlogInfo = blogInfo;
    54         }
    55 
    56         /// <summary>
    57         /// 添加一个订阅者
    58         /// </summary>
    59         /// <param name="observer">具体的订阅者对象</param>
    60         public void AddObserver(IObserver observer)
    61         {
    62             if (observers.Contains(observer))
    63             {
    64                 return;
    65             }
    66             observers.Add(observer);
    67         }
    68 
    69         /// <summary>
    70         /// 删除一个订阅者
    71         /// </summary>
    72         /// <param name="observer">具体的订阅者对象</param>
    73         public void RemoveObserver(IObserver observer)
    74         {
    75             if (observers.Contains(observer))
    76             {
    77                 observers.Remove(observer);
    78             }
    79         }
    80 
    81         /// <summary>
    82         /// 发布博客通知
    83         /// </summary>
    84         public void PublishBlog()
    85         {
    86             //遍历通知每一个订阅者
    87             foreach (IObserver ob in observers)
    88             {
    89                 if (ob != null)
    90                 {
    91                     ob.Receive(this);
    92                 }
    93             }
    94         }
    95 
    96     }
    97 }

    具体的博客类

     1 /*****************************************************
     2  * ProjectName:  _11DesignPattern_Observer
     3  * Description:
     4  * ClassName:    JiYFBlog
     5  * CLRVersion:   4.0.30319.18408
     6  * Author:       JiYF
     7  * NameSpace:    _11DesignPattern_Observer
     8  * MachineName:  JIYONGFEI
     9  * CreateTime:   2017/5/23 17:21:23
    10  * UpdatedTime:  2017/5/23 17:21:23
    11 *****************************************************/
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Linq;
    15 using System.Text;
    16 
    17 namespace _11DesignPattern_Observer
    18 {
    19 
    20     /// <summary>
    21     /// 具体的订阅博客类
    22     /// </summary>
    23     public class JiYFBlog :Blog
    24     {
    25         public JiYFBlog(string name,string blogTitile, string blogInfo)
    26             : base(name,blogTitile,blogInfo)
    27         {
    28             
    29         }
    30     }
    31 }

    订阅者接口类

     1 /*****************************************************
     2  * ProjectName:  _11DesignPattern_Observer
     3  * Description:
     4  * ClassName:    IObserver
     5  * CLRVersion:   4.0.30319.18408
     6  * Author:       JiYF
     7  * NameSpace:    _11DesignPattern_Observer
     8  * MachineName:  JIYONGFEI
     9  * CreateTime:   2017/5/23 17:09:28
    10  * UpdatedTime:  2017/5/23 17:09:28
    11 *****************************************************/
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Linq;
    15 using System.Text;
    16 
    17 namespace _11DesignPattern_Observer
    18 {
    19     /// <summary>
    20     /// 订阅者接口
    21     /// </summary>
    22     public interface IObserver
    23     {
    24 
    25         void Receive(Blog blog);
    26     }
    27 }

    具体的订阅者类:

     1 /*****************************************************
     2  * ProjectName:  _11DesignPattern_Observer
     3  * Description:
     4  * ClassName:    Observer
     5  * CLRVersion:   4.0.30319.18408
     6  * Author:       JiYF
     7  * NameSpace:    _11DesignPattern_Observer
     8  * MachineName:  JIYONGFEI
     9  * CreateTime:   2017/5/23 17:23:36
    10  * UpdatedTime:  2017/5/23 17:23:36
    11 *****************************************************/
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Linq;
    15 using System.Text;
    16 
    17 namespace _11DesignPattern_Observer
    18 {
    19     /// <summary>
    20     /// 具体的订阅者类
    21     /// </summary>
    22     public class Observer :IObserver
    23     {
    24         /// <summary>
    25         /// 订阅者名字
    26         /// </summary>
    27         private string m_Name;
    28         public string Name
    29         {
    30             get { return m_Name; }
    31             set { m_Name = value; }
    32         }
    33 
    34         /// <summary>
    35         /// 订阅者构造函数
    36         /// </summary>
    37         /// <param name="name">订阅者名字</param>
    38         public Observer(string name)
    39         {
    40             this.m_Name = name;
    41         }
    42 
    43         /// <summary>
    44         /// 订阅者接受函数
    45         /// </summary>
    46         /// <param name="blog"></param>
    47         public void Receive(Blog blog)
    48         {
    49             Console.WriteLine("订阅者:"{0}"观察到了:{1}发布的一篇博客,标题为:{2},内容为:{3}",Name,blog.BlogName,blog.BlogTitle,blog.BlogInfo);
    50         }
    51     }
    52 }

    测试代码:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace _11DesignPattern_Observer
     7 {
     8     class Client
     9     {
    10         static void Main(string[] args)
    11         {
    12             Console.WriteLine("--全部订阅者--");
    13             //创建一个JiYF的博客
    14             Blog jiyfBlog = new JiYFBlog("JiYF笨小孩","丑小鸭","丑小鸭的故事");
    15 
    16             //创建订阅者
    17             Observer obsZhangsan = new Observer("张三");
    18             Observer obsLiSi = new Observer("李四");
    19             Observer obsWangwu = new Observer("王五"); 
    20 
    21             //添加对JiYF博客的订阅者
    22             jiyfBlog.AddObserver(obsZhangsan);
    23             jiyfBlog.AddObserver(obsLiSi);
    24             jiyfBlog.AddObserver(obsWangwu);
    25 
    26             //通知订阅者
    27             jiyfBlog.PublishBlog();
    28 
    29             Console.WriteLine("--移除订阅者张三--");
    30             jiyfBlog.RemoveObserver(obsZhangsan);
    31             jiyfBlog.PublishBlog();
    32             Console.ReadLine();
    33         }
    34     }
    35 }

    运行结果:

     

    通常在C#代码中,观察者模式一般采用委托来实现如下所示

    委托实现观察者模式

    抽象博客类:

     1 /*****************************************************
     2  * ProjectName:  _11DesignPattern_ObserverDelegateTest
     3  * Description:
     4  * ClassName:    Blog
     5  * CLRVersion:   4.0.30319.42000
     6  * Author:       JiYF
     7  * NameSpace:    _11DesignPattern_ObserverDelegateTest
     8  * MachineName:  JIYF_PC
     9  * CreateTime:   2017/5/23 20:48:00
    10  * UpdatedTime:  2017/5/23 20:48:00
    11 *****************************************************/
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Linq;
    15 using System.Text;
    16 
    17 namespace _11DesignPattern_ObserverDelegateTest
    18 {
    19     /// <summary>
    20     /// 委托充当订阅者接口类
    21     /// </summary>
    22     /// <param name="sender"></param>
    23     public delegate void NotifyEventHandler(object sender);
    24 
    25     /// <summary>
    26     /// 订阅博客基类
    27     /// </summary>
    28     public class Blog
    29     {
    30         public NotifyEventHandler NotifyEvent;
    31         /// <summary>
    32         /// 博主名
    33         /// </summary>
    34         public string BlogName { get; set; }
    35 
    36         /// <summary>
    37         /// 博客标题
    38         /// </summary>
    39         public string BlogTitle { get; set; }
    40 
    41         /// <summary>
    42         /// 博客信息
    43         /// </summary>
    44         public string BlogInfo { get; set; }
    45 
    46         /// <summary>
    47         /// 博客构造函数
    48         /// </summary>
    49         /// <param name="blogTitle">博客标题</param>
    50         /// <param name="blogInfo">博客信息</param>
    51         public Blog(string name, string blogTitle, string blogInfo)
    52         {
    53             this.BlogName = name;
    54             this.BlogTitle = blogTitle;
    55             this.BlogInfo = blogInfo;
    56         }
    57 
    58         /// <summary>
    59         /// 绑定订阅事件
    60         /// </summary>
    61         /// <param name="ob">订阅者</param>
    62         public void AddObserver(NotifyEventHandler observer)
    63         {
    64             NotifyEvent += observer;
    65         }
    66 
    67         /// <summary>
    68         /// 取消绑定订阅
    69         /// </summary>
    70         /// <param name="observer"></param>
    71         public void RemoteObserver(NotifyEventHandler observer)
    72         {
    73             NotifyEvent -= observer;
    74         }
    75 
    76         /// <summary>
    77         /// 发布博客通知
    78         /// </summary>
    79         public void PublishBlog()
    80         {
    81             if(NotifyEvent != null)
    82             {
    83                 NotifyEvent(this);
    84             }
    85         }
    86     }
    87 }

    具体的博客类

     1 /*****************************************************
     2  * ProjectName:  _11DesignPattern_ObserverDelegateTest
     3  * Description:
     4  * ClassName:    JiYFBlog
     5  * CLRVersion:   4.0.30319.42000
     6  * Author:       JiYF
     7  * NameSpace:    _11DesignPattern_ObserverDelegateTest
     8  * MachineName:  JIYF_PC
     9  * CreateTime:   2017/5/23 20:55:58
    10  * UpdatedTime:  2017/5/23 20:55:58
    11 *****************************************************/
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Linq;
    15 using System.Text;
    16 
    17 namespace _11DesignPattern_ObserverDelegateTest
    18 {
    19     /// <summary>
    20     /// 具体的订阅博客类
    21     /// </summary>
    22     public class JiYFBlog : Blog
    23     {
    24         public JiYFBlog(string name, string blogTitile, string blogInfo)
    25             : base(name, blogTitile, blogInfo)
    26         {
    27 
    28         }
    29     }
    30 }

    订阅者类

     1 /*****************************************************
     2  * ProjectName:  _11DesignPattern_ObserverDelegateTest
     3  * Description:
     4  * ClassName:    Observer
     5  * CLRVersion:   4.0.30319.42000
     6  * Author:       JiYF
     7  * NameSpace:    _11DesignPattern_ObserverDelegateTest
     8  * MachineName:  JIYF_PC
     9  * CreateTime:   2017/5/23 20:56:50
    10  * UpdatedTime:  2017/5/23 20:56:50
    11 *****************************************************/
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Linq;
    15 using System.Text;
    16 
    17 namespace _11DesignPattern_ObserverDelegateTest
    18 {
    19     /// <summary>
    20     /// 具体的订阅者类
    21     /// </summary>
    22     public class Observer
    23     {
    24         /// <summary>
    25         /// 订阅者名字
    26         /// </summary>
    27         private string m_Name;
    28         public string Name
    29         {
    30             get { return m_Name; }
    31             set { m_Name = value; }
    32         }
    33 
    34         /// <summary>
    35         /// 订阅者构造函数
    36         /// </summary>
    37         /// <param name="name">订阅者名字</param>
    38         public Observer(string name)
    39         {
    40             this.m_Name = name;
    41         }
    42 
    43         /// <summary>
    44         /// 订阅者接受函数
    45         /// </summary>
    46         /// <param name="blog"></param>
    47         public void Receive(object obj)
    48         {
    49             Blog blog = obj as Blog;
    50             if (blog != null)
    51             {
    52                 Console.WriteLine("订阅者:"{0}"观察到了:{1}发布的一篇博客,标题为:{2},内容为:{3}", Name, blog.BlogName, blog.BlogTitle, blog.BlogInfo);
    53             }
    54          }
    55     }
    56 }

    测试代码

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace _11DesignPattern_ObserverDelegateTest
     7 {
     8     class Client
     9     {
    10         static void Main(string[] args)
    11         {
    12             Console.WriteLine("--全部订阅者--");
    13             //创建一个JiYF的博客
    14             Blog jiyfBlog = new Blog("JiYF笨小孩","丑小鸭","丑小鸭的故事");
    15             
    16             //创建订阅者
    17             Observer obsZhangsan    = new Observer("张三");
    18             Observer obsLiSi        = new Observer("李四");
    19             Observer obsWangwu      = new Observer("王五"); 
    20 
    21             //添加对JiYF博客的订阅者
    22             jiyfBlog.AddObserver(new NotifyEventHandler(obsZhangsan.Receive));
    23             jiyfBlog.AddObserver(new NotifyEventHandler(obsLiSi.Receive));
    24             jiyfBlog.AddObserver(new NotifyEventHandler(obsWangwu.Receive));
    25 
    26             ////通知订阅者
    27             jiyfBlog.PublishBlog();
    28 
    29             Console.WriteLine("---移除订阅者张三--");
    30             jiyfBlog.RemoteObserver(new NotifyEventHandler(obsZhangsan.Receive));
    31             jiyfBlog.PublishBlog();
    32             Console.ReadLine();
    33         }
    34     }
    35 }

    运行结果:

     

    源代码工程文件下载

  • 相关阅读:
    PHP base_convert() 函数详解
    PHP中位运算符
    MySQL中SQL Mode的查看与设置
    HTML 字符实体详情
    php7中 ?? 和 ?: 的区别
    正则表达式详解
    PHP sprintf() 函数详解
    php-config——PHP配置信息的查看
    无界工作记录
    CMake根据平台移植检查设置文件编译选项
  • 原文地址:https://www.cnblogs.com/JiYF/p/6896458.html
Copyright © 2020-2023  润新知