一、概述
在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知。如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化。使用观察者模式可以降低对象之间的依赖,以松耦合的方式实现这一目标。
二、观察者模式
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。其结构图如下:

Subject知道它的所有观察者并提供了观察者注册和删除订阅的接口。
Observer为那些在目标发生改变时需获得通知的对象定义一个更新接口。
ConcreteSubject实现Subject接口,当改变状态时向依赖于它的ConcreteObserver发送通知。
ConcreteObserver实现Observer的更新接口,使得自身能根据ConcreteSubject状态的不同而做出相应的改变。
观察者模式分为推模式和拉模式两种。推模式是当有通知时,把依赖对象的信息以参数的形式传递给所有观察者,而拉模式通知方法本身并不带任何的参数,是由观察者自己到依赖对象那里取回相关信息。在推模式下,所有观察者都通过参数传递的方式得到依赖对象的全部信息,与依赖对象之间的耦合较低,但不能实现“按需所取”所需要信息的。而拉模式仅仅是通知观察者,至于要不要提取依赖对象的信息则是观察者自己的事情,这么一来就实现“按需所取”,但往往要在ConcreteObserver里保存一个ConcreteSubject的引用,与ConcreteSubject的耦合也加强了。
观察者模式的Subject一般需要提供观察者注册和删除订阅的接口,但在.NET中,往往可以利用事件和委托的特性来实现观察者模式,这是一种更为优雅的方案。
三、示例
我们现在利用事件实现观察者模式。我们设计一个信用卡消费的简单例子,在消费的同时需要对用户账户进行扣款,同时对用户进行短信提醒。
首先定义信用卡类,当消费金额变动时会触发Notify方法通知该对象的所有观察者。

 1     public class CreditCard : EventArgs
2 {
3 private float _spendAmount;
4 public event EventHandler<CreditCard> SpendMoney;
5
6 public float SpendAmount
7 {
8 get
9 {
10 return _spendAmount;
11 }
12 set
13 {
14 _spendAmount = value;
15 Notify();
16 }
17 }
18
19 private void Notify()
20 {
21 if (SpendMoney != null)
22 {
23 SpendMoney(this, this);
24 }
25 }
26 }

接着定义Observer接口,并使用户帐户类和短信提醒类实现这个接口,其中这两个ConcreteObserver类的Update方法签名必须与CreditCard中的事件SendMoney一致,否则就无法注册到CreditCard。

 1    public interface IObserver<T>
2 {
3 void Update(Object sender, T e);
4 }
5
6 public class SMSNotify : IObserver<CreditCard>
7 {
8 public void Update(Object sender, CreditCard e)
9 {
10 Console.WriteLine("Sms notify.Spend {0}", e.SpendAmount);
11 }
12 }
13
14 public class Account : IObserver<CreditCard>
15 {
16 private float _accountAmount;
17
18 public Account(float accountAmount)
19 {
20 _accountAmount = accountAmount;
21 }
22
23 public void Update(Object sender, CreditCard e)
24 {
25 _accountAmount += e.SpendAmount;
26 Console.WriteLine("Account amount is {0}", _accountAmount);
27 }
28 }

最后看一下客户端调用。

1     static void Main(string[] args)
2 {
3 CreditCard creditCard = new CreditCard();
4 SMSNotify sms = new SMSNotify();
5 Account account = new Account(1000);
6 creditCard.SpendMoney += account.Update;
7 creditCard.SpendMoney += sms.Update;
8 creditCard.SpendAmount = 200;
9 }
 
 

C#设计模式——观察者模式(Observer Pattern)的更多相关文章

  1. 设计模式-观察者模式(Observer Pattern)

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

  2. 设计模式 - 观察者模式(Observer Pattern) 详细说明

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  3. 设计模式 - 观察者模式(Observer Pattern) 详细解释

    观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  4. 设计模式 - 观察者模式(Observer Pattern) Java内置 用法

    观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...

  5. C#设计模式——观察者模式(Observer Pattern)1

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  6. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  7. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  8. 二十四种设计模式:观察者模式(Observer Pattern)

    观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...

  9. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

随机推荐

  1. SqlServer数据库备份与还原

    http://v.youku.com/v_show/id_XMjA4NzcyNzUy.html http://v.youku.com/v_show/id_XMjA4Nzc0NDQw.html

  2. vs2010 使用vs online账号 需要安装的插件

    VS10SP1-KB2662296.exe http://pan.baidu.com/s/1qWDpEG0 vs2010 需要先升级到SP1

  3. window下,加载redis拓展

    下载地址: http://windows.php.net/downloads/pecl/snaps/redis/2.2.5/ 看下自己phpinfo的信息          就选择   ts-x86 ...

  4. 【国内独家首发】iPhone4 iOS7不完美越狱教程新鲜出炉

    准备工作: 1.Mac (OSX 10.8以上系统): 2.iPhone 4 (iPhone3, 1 iOS 7.0.2): 3.iPhone 4数据线一根: 4.下载越狱工具包:ios7_jb_ki ...

  5. dolby逝世:纪念一下

     杜比公司的成立快50年了(1965),想想中国1965年在干啥.中国怎么可能有.   小科普一下,dolby的成功有3个时间点和技术,第一次是在英国开发了dolby B降噪技术,是用在早期的卡带降噪 ...

  6. freemarker springmvc配置异常

    异常信息 java.lang.IllegalAccessError: tried to access method freemarker.ext.servlet.AllHttpScopesHashMo ...

  7. 如何改变Activity在当前任务堆栈中的顺序,Intent参数大全

    引用:http://blog.csdn.net/think_soft/article/details/7477072 本示例演示如何通过设置Intent对象的标记,来改变当前任务堆栈中既存的Activ ...

  8. 操作系统性能分析与优化V1.0

    操作系统性能分析与优化V1.0 : http://www.docin.com/p-759561760.html

  9. Tomcat Manager 用户名和密码配置

    在Tomcat中,应用程序的部署很简单,只需将你的WAR放到Tomcat的webapp目录下,Tomcat会自动检测到这个文件,并将其解压.在浏览器中访问这个应用的Jsp时,通常第一次会很慢,因为To ...

  10. 多个Storyboard的使用

    创建一个Storyboard工程 storyboard是在ios5中引入的新控件,能够更加清晰.简单的整合多个ViewController的关系,下面主要介绍一下怎么初建一个storyboard的工程 ...