索引

别名

  • Dependency
  • Publish-Subscribe

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

结构

参与者

Subject

  • Subject 知道它的 Observer。可以有任意多个 Observer 观察同一个 Subject。
  • 提供注册和删除 Observer 的接口。

Observer

  • 为那些在 Subject 发生改变时需要获得通知的对象定义一个 Update 接口。

ConcreteSubject

  • 将有关状态存储各个 ConcreteObserver 对象。
  • 当它的状态发生改变时,想它的各个 Observer 发出通知。

ConcreteObserver

  • 维护一个指向 ConcreteSubject 对象的引用。
  • 存储有关状态,这些状态应该与 ConcreteSubject 的状态保持一致。
  • 实现 Observer 的更新接口以使自身状态与 ConcreteSubject 状态保持一致。

适用性

在以下情况下可以使用 Observer 模式:

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  • 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象时谁。

效果

  • 目标与观察者间的抽象耦合。
  • 支持广播通信。
  • 意外的更新。因为 Observer 并不知道其他 Observer 的存在,所以对改变 Subject 的最终代价一无所知。

相关模式

  • 可以使用 Mediator 模式封装复杂的更新语义,充当 Subject 与 Observer 之间的中介者。

实现

下面的交互图描述 Subject 与 Observer 之间的协作:

实现方式(一):Observer 模式结构样式代码。

推模式(Push Model):Subject 向 Observer 发送关于改变的详细信息,而不管它们是否需要。

拉模式(Pull Model):Subject 除最小通知外什么也不推送,由 Observer 显式地向 Subject 询问细节。

 namespace ObserverPattern.Implementation1
{
public abstract class Observer
{
public abstract void Update();
} public abstract class Subject
{
private List<Observer> _observers = new List<Observer>(); public void Attach(Observer observer)
{
_observers.Add(observer);
} public void Detach(Observer observer)
{
_observers.Remove(observer);
} public void Notify()
{
foreach (var observer in _observers)
{
observer.Update();
}
}
} public class ConcreteSubject : Subject
{
private string _state; public string State
{
get
{
return _state;
}
set
{
_state = value;
Notify();
}
}
} public class ConcreteObserver : Observer
{
private ConcreteSubject _subject; public ConcreteObserver(string name, ConcreteSubject subject)
{
Name = name;
_subject = subject;
} public string Name { get; private set; } public override void Update()
{
string subjectState = _subject.State;
Console.WriteLine(Name + ": " + subjectState);
}
} public class Client
{
public void TestCase1()
{
var subject = new ConcreteSubject();
subject.Attach(new ConcreteObserver("Observer 1", subject));
subject.Attach(new ConcreteObserver("Observer 2", subject));
subject.Attach(new ConcreteObserver("Observer 3", subject)); subject.State = "Hello World";
}
}
}

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

设计模式之美:Observer(观察者)的更多相关文章

  1. 深入浅出设计模式——观察者模式(Observer Pattern)

    模式动机 建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应.在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而 ...

  2. 设计模式之美:Mediator(中介者)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Mediator 模式结构样式代码. 意图 用一个中介对象来封装一系列的对象交互. 中介者使各对象不需要显式地相互引用,从而使其 ...

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

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

  4. 8.5 GOF设计模式四: 观察者模式Observer

    GOF设计模式四: 观察者模式Observer  现实中遇到的问题  当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式  观察者模式 ...

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

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 观察者模式简述 观察者模式的使用非常广泛,常用于建立起一种多对一的关系,该模式一定会包含两个角色 ...

  6. java设计模式解析(1) Observer观察者模式

      设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析( ...

  7. 设计模式-观察者模式(Observer Model)

    文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6031844.html LZ刚刚开始心热的开启了博客之路,想着记点流水账,可帝都的天都冷成 ...

  8. 设计模式之美:Product Trader(操盘手)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规约来创建对象. Product Trad ...

  9. 设计模式之美:Null Object(空对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...

随机推荐

  1. Dreamweaver 升级问题汇总

    Adobe的产品开始从CC (Creative Cloud) 开始转向云平台,CS将逐渐成为过去时.不过CC并不限制用户在同一台机器上同时使用CS和CC,这种策略估计要持续较长一段时间. If you ...

  2. Eclipse导入Maven项目,使用server 启动报错,class 找不到,

    问题发现: 1.导入maven 项目后,用server 启动,选择项中没有这个项目 解决: 说明server 没有把该项目当成web项目,需要设置 项目右键 properties  ---- proj ...

  3. savepic

    #-*-coding:utf-8-*-from lxml import etreeimport requestsfrom urllib import urlretrieveimport osdef g ...

  4. 【SQLServer】“无法对数据库’XXX’ 执行删除,因为它正用于复制”的解决方法

    警告: 一个或多个现有列的 ANSI_PADDING 设置为 "off",将以 ANSI_PADDING 为 "on" 的设置重新创建 [SQLServer]& ...

  5. sed笔记

    sed是stream editor缩写,表示流编辑器,它是一款文本处理工具,可以配合正则表达式进行文本替换. 1.使用正则表达式匹配并进行文本中的字符串替换 *使用-i选项可以直接将替换结果应用到源文 ...

  6. Windows Desktop 调用 WinRT api

    <Reference Include="Windows"> <HintPath>..\..\..\..\..\..\Program Files (x86)\ ...

  7. centos 如何清理/dev/vda1系统盘

    df-h检查一台服务器磁盘使用空间,发现磁盘已经使用了100% 思路是: 1.cd /usr 2.du -sh * 看哪个目录占用空间大 3.重复前两步,根据实际情况删除或者移走 4.日志的话可以运行 ...

  8. ROS BY EXAMPLE 1 -- 环境设置与安装

    rbx1 package 的环境设置: sudo apt-get install ros-indigo-turtlebot-bringup \ ros-indigo-turtlebot-create- ...

  9. 基音周期提取2-基于线性相关系数的Matlab实现

    基音周期提取2-基于线性相关系数的Matlab实现 基音周期提取结果 图1 基音提取结果 算法说明 线性相关系数 也称"皮尔逊积矩相关系数"(Pearson product-mom ...

  10. Session管理解决方案笔记

    大型网站Session管理解决方案: 1. web服务器之间的session复制.    优点:方案成熟    缺点:复制的性能开销大 2. 减少session使用,使用客户端存储cookie     ...