设计模式 - observer
简单来讲,就是observer依赖于subject,当subject发生变化时,observer得到通知,并将状态与subject同步,常来用于维护对象间状态的一致性。

observer的工作过程大体如下:
注册:
observer将自身注册到subject中,subject中通常保有一份注册的observer列表。
通知:
当subject发生变化时,会遍历自身保有的观察者列表,并调用observer的update方法,更新其自身状态
销毁:
当注销时,销毁subject中的observer即可。
缺陷:
a. 观察者模式中的observer并不知道对方的存在,因此在subject中状态改变后,难以预料对其他observer的影响。
b. 当删除subject中,需要注意去除observer中的悬挂引用。通常的解决方案是在删除subject时,通知observer进行处理。
改进:
观察者模式的核心是依赖关系,上面的例子中,observer和subject的关系尤其自身来保存,但当遇到复杂的依赖和注册关系,以及不同的通知机制时,可以通过抽象出changeManager来减少observer反应其变更的工足量。
如:如果一个操作涉及到几个相互依赖的目标进行改动,就必须保证在所有目标都已经更新完毕后,才一次性通知其observer,而非每个subject分别通知。
代码示例:
package com.inspur.jiyq.designpattern.observer; import com.inspur.jiyq.designpattern.observer.impl.ConcreteObserver;
import com.inspur.jiyq.designpattern.observer.impl.ConcreteSubject; public class ObserverMain {
public static void main(String[] args)
{
Subject subject = new ConcreteSubject(); //observer注册到suject中
ConcreteObserver observer1 = new ConcreteObserver(subject);
ConcreteObserver observer2 = new ConcreteObserver(subject); subject.notice();
}
}
package com.inspur.jiyq.designpattern.observer;
public interface Subject {
/**
* 注册observer
*/
public void attach(Observer observer);
/**
* 注销 observer
*/
public void detach(Observer observer);
/**
* 通知observer
*/
public void notice();
/**
* 获取内部状态
* @return
* 内部状态
*/
public String getState();
/**
* 设置内部状态
*
* @param innerState
* 内部状态
*/
public void setState(String innerState);
}
package com.inspur.jiyq.designpattern.observer;
public interface Observer {
public void update(Subject subject);
}
package com.inspur.jiyq.designpattern.observer.impl; import java.util.ArrayList;
import java.util.List; import com.inspur.jiyq.designpattern.observer.Observer;
import com.inspur.jiyq.designpattern.observer.Subject; public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<Observer>(); private String innerState = null; @Override
public void attach(Observer observer) {
this.observers.add(observer);
} @Override
public void detach(Observer observer) {
this.observers.remove(observer);
} @Override
public void notice() {
for (Observer observer : observers) {
// 将自身状态更新至observer,保证状态一致性
observer.update(this);
}
} /**
* 返回自身状态
*/
@Override
public String getState() {
return innerState;
} /**
* 返回自身状态
*/
public void setState(String innerState) {
this.innerState = innerState;
}
}
package com.inspur.jiyq.designpattern.observer.impl; import com.inspur.jiyq.designpattern.observer.Observer;
import com.inspur.jiyq.designpattern.observer.Subject; public class ConcreteObserver implements Observer {
Subject subject; public ConcreteObserver(Subject subject)
{
this.subject= subject;
subject.attach(this);;
} @Override
public void update(Subject subject) {
System.out.println("I got a new state.");
}
}
设计模式 - observer的更多相关文章
- (java)从零开始之--观察者设计模式Observer
观察者设计模式:时当一个对象发生指定的动作时,要通过另外的对象做出相应的处理. 步骤: 1. A对象发生指定的动作是,要通知B,C,D...对象做出相应的处理,这时候应该把B,C,D...对象针对A对 ...
- [C++设计模式]observer 观察者模式
有这么一种松耦合的需求: 有一些类的对象对类A对象的状态变化非常感兴趣,不会改变类A的对象,也不会被类A的对象改变,想以一种较小的代价观察对类A对象状态变化. 以下的几种方式也能实现上述目的 (1)通 ...
- C++设计模式-Observer观察者模式
Observer观察者模式作用:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己 UML图: S ...
- Java设计模式——Observer(观察者)模式
在多个对象之间建立一对多的关系,以便当一个对象状态改变的时候.其它全部依赖于这个对象的对象都能得到通知,并被自己主动更新. 适用情况: 当一个抽象模型有两个方面,当中一个方面依赖于还有一方面. 将这二 ...
- javascript设计模式——Observer
定义一种一对多的从属关系,当一个目标状态改变,所有他的从属对对象都将收到通知. 1.简单的Observer模式 实现 var Observer = function(){ this.list = [] ...
- 设计模式のObserver Pattern(观察者模式)----行为模式
一.问题产生背景 又被称为订阅发布模式. 最初流传最广的一个面试题:有一只猫咪,猫咪叫了一声,老鼠跑了,老人惊醒了,男主人骂,小偷吓得不敢动了....这就产生一个问题的模型,当对象间存在一对多关系时, ...
- java设计模式-Observer(2)
一.模拟AWT事件处理 回顾一下JDK里面按下一个Button,有件事发生,这个东西怎么写: package com.cy.dp.observer.awt; import java.awt.Butto ...
- Java 设计模式 – Observer 观察者模式
目录 [隐藏] 1 代码 1.1 观察者接口: 1.2 被观察者: 1.3 观众类 : 1.4 电影类: 1.5 效果如下: 代码 说明都在注释: 观察者接口: package ObserverMod ...
- C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介
委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...
随机推荐
- ECSHOP 支付宝发货确认接口,记录支付宝返回的交易号
1,在order_info 数据表尾添加trade_no 字段 数据表尾怎么添加trade_no 字段 ECSHOP为了支付宝发货确认接口,需要记录支付宝返回的交易号 1,在order_info 数据 ...
- 阿里云服务器无法远程其他的mysql服务器
1.初始化root密码 进入mysql数据库 1 mysql>update user set password=PASSWORD('123456') where User='root'; 2.允 ...
- [Learn Android Studio 汉化教程]第三章:使用 Android Studio 编程
[Learn Android Studio 汉化教程]第三章:使用 Android Studio 编程 本章包含如何在 Android Studio 中书写或生成代码. Android Studio ...
- 【socket】一分钟理清 socket udpsocket tcpsocket tcplistener TCPClient和 UDPClient
socket 套接字接口是各种语言tcp udp的网络操作的基础. 直接用socket 对象开发 可以选择 udpsocket 或者 tcpsocket ,两者在使用上仅一些方法和参数不同,所有的底 ...
- mybatis从dao传入多个参数到sqlmap时dao中要使用map或实例对象(如:user)作为参数传入, 否则报错找不到属性getter方法
23:37 2015-07-02 注意1. 使用mybaits的resultMap查询时, 如果想传入多个参数(比如where 1=1动态多条件查询时)sqlmap文件中对应的方法中, selectL ...
- linux安装软件命令
tar.bz2的解压: tar -jxvf FileName.tar.bz2 然后安装: cd FileName ./configure make make install rpm 包的安装: rpm ...
- maven3.1安装及配置
1.首先下载maven3,并安装 2.环境变量配置与JAVA_HOME的配置一样 3.打开MyEclipse preferences>>Maven4MyEclipse>>Mav ...
- Jquery实现自动提示下拉框
1.引入脚本库: <script type="text/javascript" src="/Jscripts/jquery-1.3.2.js"&g ...
- 反射自动填充model
public static T FillModel<T>(DataRow dr) { ) return default(T); T model = Activator.CreateInst ...
- 1061: [Noi2008]志愿者招募 - BZOJ
Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完 ...