设计模式之美:Observer(观察者)
索引
别名
- 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(观察者)的更多相关文章
- 深入浅出设计模式——观察者模式(Observer Pattern)
模式动机 建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应.在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而 ...
- 设计模式之美:Mediator(中介者)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Mediator 模式结构样式代码. 意图 用一个中介对象来封装一系列的对象交互. 中介者使各对象不需要显式地相互引用,从而使其 ...
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 8.5 GOF设计模式四: 观察者模式Observer
GOF设计模式四: 观察者模式Observer 现实中遇到的问题 当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式 观察者模式 ...
- 设计模式-观察者模式(Observer Pattern)
本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 观察者模式简述 观察者模式的使用非常广泛,常用于建立起一种多对一的关系,该模式一定会包含两个角色 ...
- java设计模式解析(1) Observer观察者模式
设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析( ...
- 设计模式-观察者模式(Observer Model)
文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6031844.html LZ刚刚开始心热的开启了博客之路,想着记点流水账,可帝都的天都冷成 ...
- 设计模式之美:Product Trader(操盘手)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规约来创建对象. Product Trad ...
- 设计模式之美:Null Object(空对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...
随机推荐
- mysql中的where和having子句的区别
mysql中的where和having子句的区别 having的用法 having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句 ...
- cod-hw
COD hw 4 Xinglu Wang 3140102282 2016-12-27 21:28:01 COD hw 45.35.3.15.3.35.3.45.3.55.3.65.45.4.15.4. ...
- 第一节(配置springmvc环境)学习尚硅谷-springmvc视频教程
之前,一直从事C#开发.后来,公司调整后领导决定使用java开发,因此需要收集相关学习资料.该视频教程比较入门,也适合自己,于是边看边写的同时再总结一下便于自己牢记,遇到分歧不对之处望指正. 开发环境 ...
- 深入研究C语言 第四篇
这里更多探究的是指针的机制. 用debug对下面程序进行分析,记录每一条C语句运行后,相关内存单元的值. 程序a.c 注意理解指针机制 我们编写如下代码: 编译加载进debug查看: 我们先看其反汇编 ...
- 用JDBC做账号注册登陆
一.先用JDBC做账号登陆 方法一:用createStatement方法做账号登陆 测试结果:当输入正确账号密码时:当输入错误账号密码时: 当用注入攻击输入账号密码时: 注入攻击的原理是 输入任意值' ...
- Tomcat如何配置环境变量
1, JDK:版本为jdk-7-windows-i586.exe 下载地址: http://www.oracle.com/technetwork/java/javase/downloads/index ...
- JavaScript-计算器
事件周期 DOM:3个阶段 1.捕获:从最外层元素,向内层元素,逐个记录绑定的事件处理函数.默认,暂不触发任何事件 2.目标触发:优先触发目标元素绑定的事件处理函数 目标元素:实际点击的元素 3.冒泡 ...
- 关于display: box 和 box-flex
这两天做手机项目,使用到这个css3新属性.现在还不为所有浏览器支持,所以使用的时候要加上前缀.使用方法见下面: html代码: <div class="s-indLine" ...
- !important
当你需要确保某元素具有指定的 CSS 时,你可以使用!important. 举例如下: color: pink !important;
- [UCSD白板题] Compute the Edit Distance Between Two Strings
Problem Introduction The edit distinct between two strings is the minimum number of insertions, dele ...