• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C# 设计模式系列教程-观察者模式

C# 设计模式系列教程-观察者模式

作者:Wang Juqiang 字体:[增加 减小] 来源:互联网 时间:2017-05-28

Wang Juqiang 通过本文主要向大家介绍了c#观察者模式,观察者模式,代理模式 观察者模式,我的世界观察者模式,观察者模式java等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

1. 概述

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

2. 解决的问题

  将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。

3. 模式中的角色

  3.1 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

  3.2 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。

  3.3 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

  3.4 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

4. 模式解读

  4.1 观察者模式的类图  

/UpFiles/2017/5/28/201606010917421.png

  4.2 观察者模式的代码

 /// <summary>
 /// 抽象主题类
 /// </summary>
 public abstract class Subject
 {
 private IList<Observer> observers = new List<Observer>();

 /// <summary>
 /// 增加观察者
 /// </summary>
 /// <param name="observer"></param>
 public void Attach(Observer observer)
 {
  observers.Add(observer);
 }

 /// <summary>
 /// 移除观察者
 /// </summary>
 /// <param name="observer"></param>
 public void Detach(Observer observer)
 {
  observers.Remove(observer);
 }

 /// <summary>
 /// 向观察者(们)发出通知
 /// </summary>
 public void Notify()
 {
  foreach (Observer o in observers)
  {
  o.Update();
  }
 }
 }

 /// <summary>
 /// 抽象观察者类,为所有具体观察者定义一个接口,在得到通知时更新自己
 /// </summary>
 public abstract class Observer
 {
 public abstract void Update();
 }

 /// <summary>
 /// 具体观察者或具体通知者,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。
 /// </summary>
 public class ConcreteSubject : Subject
 {
 private string subjectState;

 /// <summary>
 /// 具体观察者的状态
 /// </summary>
 public string SubjectState
 {
  get { return subjectState; }
  set { subjectState = value; }
 }
 }

 /// <summary>
 /// 具体观察者,实现抽象观察者角色所要求的更新接口,已是本身状态与主题状态相协调
 /// </summary>
 public class ConcreteObserver : Observer
 {
 private string observerState;
 private string name;
 private ConcreteSubject subject;

 /// <summary>
 /// 具体观察者用一个具体主题来实现
 /// </summary>
 public ConcreteSubject Subject
 {
  get { return subject; }
  set { subject = value; }
 }

 public ConcreteObserver(ConcreteSubject subject, string name)
 {
  this.subject = subject;
  this.name = name;
 }

 /// <summary>
 /// 实现抽象观察者中的更新操作
 /// </summary>
 public override void Update()
 {
  observerState = subject.SubjectState;
  Console.WriteLine("The observer's state of {0} is {1}", name, observerState);
 }
 }
</div>

  4.3 客户端代码

 class Program
 {
 static void Main(string[] args)
 {
  // 具体主题角色通常用具体自来来实现
  ConcreteSubject subject = new ConcreteSubject();

  subject.Attach(new ConcreteObserver(subject, "Observer A"));
  subject.Attach(new ConcreteObserver(subject, "Observer B"));
  subject.Attach(new ConcreteObserver(subject, "Observer C"));

  subject.SubjectState = "Ready";
  subject.Notify();

  Console.Read();
 }
 }
</div>


  运行结果

/UpFiles/2017/5/28/201606010917422.png

5. 模式总结

  5.1 优点

    5.1.1 观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。

  5.2 缺点

    5.2.1 依赖关系并未完全解除,抽象通知者依旧依赖抽象的观察者。

  5.3 适用场景

    5.3.1 当一个对象的改变需要给变其它对象时,而且它不知道具体有多少个对象有待改变时。

    5.3.2 一个抽象某型有两个方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。

 

6. 模式引申,应用C#中的事件委托来彻底解除通知者和观察者之间的耦合。

   6.1 关于委托的定义:委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法有相同的行为。委托方法可以像其它任何方法一样,具有参数和返回值。委托可以看作是对函数(方法)的的抽象,是函数的“类”,委托的实例代表一个(或多个)具体的函数,它可以是多播的。

   6.2 关于事件:事件基于委托,为委托提供了一种发布/订阅机制。事件的订阅与取消与我们刚才讲的观察者模式中的订阅与取消类似,只是表现形式有所不同。在观察者模式中,订阅使用方法Attach()来进行;在事件的订阅中使用“+=”。类似地,取消订阅在观察者模式中用Dettach(),而事件的取消用“-=”。

 

7. 下面例子分别用观察者模式,事件机制来实现

  7.1 实例描述:客户支付了订单款项,这时财务需要开具发票,出纳需要记账,配送员需要配货。

  7.2 观察者模式的实现

    7.2.1 类图

/UpFiles/2017/5/28/201606010917423.png

    7.2.2 代码实现

 /// <summary>
 /// 抽象观察者
 /// </summary>
 public interface ISubject
 {
 void Notify();
 }

 /// <summary>
 /// 工作岗位,作为这里的观察者的抽象
 /// </summary>
 public abstract class JobStation
 {
 public abstract void Update();
 }

 /// <summary>
 /// 具体主题,这里是客户
 /// </summary>
 public class Customer : ISubject
 {
 private string customerState;

 private IList<JobStation> observers = new List<JobStation>();

 /// <summary>
 /// 增加观察者
 /// </summary>
 /// <param name="observer"></param>
 public void Attach(JobStation observer)
 {
  this.observers.Add(observer);
 }

 /// <summary>
 /// 移除观察者
 /// </summary>
 /// <param name="observer"></param>
 public void Detach(JobStation observer)
 {
  this.observers.Remove(observer);
 }

 /// <summary>
 /// 客户状态
 /// </summary>
 public string CustomerState
 {
  get { return customerState; }
  set { customerState = value; }
 }

 public void Notify()
 {
  foreach (JobStation o in observers)
  {
  o.Update();
  }
 }
 }

 /// <summary>
 /// 会计
 /// </summary>
 public class Accountant : JobStation
 {
 private string accountantState;
 private Customer customer;

 public Accountant(Customer customer)
 {
  this.customer = customer;
 }

 /// <summary>
 /// 更新状态
 /// </summary>
 public override void Update()
 {
  if (customer.CustomerState == "已付款")
  {
  Console.WriteLine("我是会计,我来开具发票。");
  accountantState = "已开发票";
  }
 }
 }

 /// <summary>
 /// 出纳
 /// </summary>
 public class Cashier : JobStation
 {
 private string cashierState;
 private Customer customer;

 public Cashier(Customer customer)
 {
  this.customer = customer;
 }

 public override void Update()
 {
  if (customer.CustomerState == "已付款")
  {
  Console.WriteLine("我是出纳员,我给登记入账。");
  cashierState = "已入账";
  }
 }
 }

 /// <summary>
 /// 配送员
 /// </summary>



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C# 设计模式系列教程-观察者模式
  • C#中观察者模式的3种实现方式
  • C#观察者模式(Observer Pattern)实例教程
  • C#中委托和事件在观察者模式中的应用实例
  • 简单的观察者模式示例分享
  • C# 观察者模式实例介绍

相关文章

  • 2017-05-28浅谈C#2.0泛型中的变化:default关键字
  • 2017-05-28C#通过DataSet读写xml文件的方法
  • 2017-05-28c#实现ini文件读写类分享
  • 2017-05-28C# 面向对象三大特性:封装、继承、多态
  • 2017-05-28c#多线程编程基础
  • 2017-05-28.net C# 实现任意List的笛卡尔乘积算法代码
  • 2017-05-28C#中静态的深入理解
  • 2017-05-28C#简单遍历指定文件夹中所有文件的方法
  • 2017-05-28浅谈C#中的for循环与foreach循环
  • 2017-05-28C#实现ListView选中项向上或向下移动的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 浅谈C# 类的继承
    • C# 6.0 新特性汇总
    • C#中volatile与lock用法
    • 举例讲解C#中自动实现的属性
    • c#中Winform实现多线程异步更新UI(进度及状态信息)
    • 深入C#判断操作系统类型的总结详解
    • C#实现属于自己的QQ截图工具
    • c# n个数排序实现代码
    • Visual Studio中根据系统区分引用64位、32位DLL动态库文件的配置方法
    • c#格式化数字的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有