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. }

运行结果:

源代码工程文件下载

C#设计模式--观察者模式(发布-订阅模式)的更多相关文章

  1. 设计模式 | 观察者模式/发布-订阅模式(observer/publish-subscribe)

    定义: 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 结构:(书中图,侵删) 一个抽象的观察者接口, ...

  2. [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  3. C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命

    使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠 ...

  4. JavaScript设计模式(发布订阅模式)

    发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在JavaScript开发中,我们一般用事件模型来替代传统的发布—订阅模式 ...

  5. SpringBoot事件监听机制及观察者模式/发布订阅模式

    目录 本篇要点 什么是观察者模式? 发布订阅模式是什么? Spring事件监听机制概述 SpringBoot事件监听 定义注册事件 注解方式 @EventListener定义监听器 实现Applica ...

  6. javaScript设计模式:发布订阅模式

    发布订阅模式的思想是在观察者模式的基础上演变而来,在观察者模式中客户端监听到对象某个行为就触发对应任务程序.而在发布订阅模式中依然基于这个核心思想,所以有时候也会将两者认为是同一种设计模式.它们的不同 ...

  7. js设计模式之发布/订阅模式模式

    一.前言 发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知. 就和用户 ...

  8. 浅谈js设计模式之发布 — 订阅模式

    发布 — 订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在 JavaScript开发中,我们一般用事件模型来替代传统的发布 — ...

  9. Javascript设计模式之发布-订阅模式

    简介 发布-订阅模式又叫做观察者模式,他定义了一种一对多的依赖关系,即当一个对象的状态发生改变的时候,所有依赖他的对象都会得到通知. 回忆曾经 作为一名前端开发人员,给DOM节点绑定事件可是再频繁不过 ...

  10. javascript中的设计模式之发布-订阅模式

    一.定义 又叫观察者模式,他定义对象间的依照那个一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将的到通知.在javascript中,我们一般用时间模型来替代传统的发布-订阅模式 二 ...

随机推荐

  1. android 布局文件 ScrollView 中的 listView item 显示不全解决方案

    import android.content.Context;import android.util.AttributeSet;import android.widget.ListView; /** ...

  2. selenium+python自动化78-autoit参数化与批量上传

    前言 前一篇autoit实现文件上传打包成.exe可执行文件后,每次只能传固定的那个图片,我们实际测试时候希望传不同的图片. 这样每次调用的时候,在命令行里面加一个文件路径的参数就行. 一.命令行参数 ...

  3. 在 Gradle 中使用 MyBatis Generator

    在 Intellij IDEA 中结合 Gradle 使用 MyBatis Generator 逆向生成代码 Info: JDK 1.8 Gradle 2.14 Intellij IDEA 2016. ...

  4. Go语言之高级篇beego框架之cookie与session

    1.cookie的用法 this.Ctx.SetCookie("name", name, maxage, "/") this.Ctx.SetCookie(&qu ...

  5. jQuery()方法的第二个参数

    关于jQuery()方法的第二个参数,有下面这几种用法: 1.jQuery(selector, [context]) 这种用法,相当于 $(context).find(selector) 或者 con ...

  6. 【Spark】Spark-架构

    Spark-架构 Spark Master at spark://node-01:7077 spark clustermanager_百度搜索 看了之后不再迷糊-Spark多种运行模式 - 简书 Sp ...

  7. sql server 多表关联更新 update

    update a set a.KSMC = b.name from JC_KSXXB a inner join chisdb_ymyy..zd_unit_code b on a.KSDM = b.co ...

  8. tmux手册中文翻译

    man tmux可以看到最详细的tmux介绍,本文翻译自tmux手册. tmux全名叫"terminal multiplexer",终端多路复用器. tmux的命令格式为: tmu ...

  9. elasticsearch 支持中英文搜索和混合搜索

    环境: ubuntu16.04 安装: elasticsearch 5.22 1. 第一步,安装java apt-get install default-jre apt-get install def ...

  10. ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

    开发说测试环境在删除表的时候,报了如下错误: SQL> drop table tke purge; drop table tke purge * ERROR at line 1: ORA-000 ...