Java设计模式の观察者模式(推拉模型)
目录:
一.观察者定义
二.观察者模式的结构(推模式实现)
三.推模型和拉模型(拉模式实现)
四.JAVA提供的对观察者模式的支持
五.使用JAVA对观察者模式的支持(自带推模式实现实例)
一.观察者定义
在阎宏博士的《JAVA与模式》一书中开头是这样描述观察者(Observer)模式的:
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
二.观察者模式的结构(推模式实现实例)
一个软件系统里面包含了各种对象,就像一片欣欣向荣的森林充满了各种生物一样。在一片森林中,各种生物彼此依赖和约束,形成一个个生物链。一种生物的状态变化会造成其他一些生物的相应行动,每一个生物都处于别的生物的互动之中。
同样,一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其他的对象做出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作。观察者模式是满足这一要求的各种设计方案中最重要的一种。
下面以一个简单的示意性实现为例,讨论观察者模式的结构。
aaarticlea/png;base64,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YgsrdrVusXQ9bCurtbywCxZLdyyWPgTFdQ56nQlSGr3jJE3TrBGGauUmSGxhxa5WTyKBGCUsRJNQNyQDQ0SfflJmsXQWSxcorjORpzHxO9u2DUOTBjfqdxdvmJWbILGFFbvaM/3hWAgci6UTt8I6VyzYOOUafMy/6K/mPU1ObFwPKzdBYgsrdvVAuYUdi6WbwpBdkUHYg2QNrNjVY4krMQTtyjofP358IvP48ccf926CGT5+/Li3ac+C4koOCu2KPAivr6+fPn3697//vXdDyJJQXMlBoV2RR+Dr168vLy9vb2+fPn36z3/+s3dzyGJQXMlBoV2RR+Cnn37Cgr3//ve/nz59ent727tFZBkorkdEakE/8oJX2hU5PX/88ccvv/wi//7666+//fbbju0hC7KkuOqSUstG/I8lfEACxeljURpd73bwauR6kev86lfrMfbjr12gl+JKzs23b99eXl6+ffsmW97e3p6fn//666/9GkUWY0lxbZpGCigu6HJ1XRcufke6CedcURQTJeFQfsd9rwQ3VZXaGJ3UyV2yme/XnOEfX1g8haSG4krOzS+//PLHH394G798+fL58+c9mkMWZjFxxTr9qqqQd+l9FTbmFx/WzuiEb+flRESWhiMn7w3lajAx8kGguBLyPuq6/umnnwbf+vnnn//888+N20MWZzFxTdM0iqJYAXcHfhjKgOujBnV0rFh6KNVzBBI5F/Uh8HHl2MEa5qGShY0X53KOSIf125umGUxnMTjQitSPVz8FZ5ufBnmQmT++7ElxJeQdvL29vby8fP36dfDdb9++PT8///333xu3iizLksPCuo4pXiDNL8RMlxBHFTloyXSx9L7vvbJ0g3v2fS+Zh1EtoO/7sGYq/s3zHIdXVSXygNp2yGOsk5hD77VO40vBQUeKYDejWLrMpKLxkEzk5JPPGnxi8AqtT1AUxdX060gwi2eFqqpEtvHaG3UY/PHxUzRNo7/yGlBcyVl5fX19fX2d2OH333/nslfrrCuuTlWwEbfMcyini6WDMOV6uCdEC+eHYHviKg2AtGOjCCHUAhvlhR6S1Xn24zgWWZLngLBYuhYq7YBC3aXZ01+/aZplHURJ765d0omaQt6PrwWVnishtyILW6d347JX6yw55wrXB56WiISuhyXapiVkKXGVU4lu6WqyTmmtPlYLcJIkKLajT9g0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" alt="" />
观察者模式所涉及的角色有:
● 抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
● 具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
● 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
● 具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
观察者模式源码示例:
package com.blankjor.observer; /**
* 抽象观察者角色
*
* @author Blankjor
*
*/
public interface Observer {
void update(String state); String getName();
} package com.blankjor.observer; /**
* @desc 具体观察者
* @author Blankjor
* @date 2017年5月13日 下午5:11:52
*/
public class ConcreteObserver implements Observer { private String name;
private String state; public ConcreteObserver(String name) {
this.name = name;
} public String getState() {
return state;
} public void setState(String state) {
this.state = state;
} @Override
public void update(String state) {
// 更新观察着状态
this.state = state;
System.out.println(getName() + "观察者状态更新为:" + state);
} @Override
public String getName() {
return name;
} } package com.blankjor.observer; import java.util.ArrayList;
import java.util.List; /**
* 抽象主题角色类
*
* @author aibaibai
*
*/
public abstract class Subject {
/**
* 保存观察者的容器
*/
private List<Observer> list = new ArrayList<Observer>(); /**
* 注册观察者
*/
public void register(Observer o) {
list.add(o);
System.out.println("增加了一个观察者:" + o.getName());
} /**
* 移除观察者
*
* @param o
*/
public void remove(Observer o) {
System.out.println("移除了一个观察者:" + o.getName());
list.remove(o);
} /**
* 通知观察者
*
* @param newState
*/
public void nodifyObservers(String newState) {
for (Observer observer : list) {
observer.update(newState);
}
}
} package com.blankjor.observer; /**
* 具体主题角色
*
* @author aibaibai
*
*/
public class ConcreteSubject extends Subject {
/**
* 状态
*/
private String state; public String getState() {
return state;
} public void change(String newState) {
state = newState;
System.out.println("状态变为:" + newState);
System.out.println("开始通知观察者...");
this.nodifyObservers(state);
} } package com.blankjor.observer; /**
* @desc 测试观察者模式
* @author Blankjor
* @date 2017年5月13日 下午5:18:30
*/
public class MainTest {
public static void main(String[] args) {
Observer o1 = new ConcreteObserver("o1");
Observer o2 = new ConcreteObserver("o2");
Observer o3 = new ConcreteObserver("o3");
ConcreteSubject csj = new ConcreteSubject();
csj.register(o1);
csj.register(o2);
csj.register(o3);
csj.remove(o2);
csj.change("new State!");
}
}
测试观察者结果:
在运行时,这个客户端首先创建了具体主题类的实例,以及一个观察者对象。然后,它调用主题对象的register()方法,将这个观察者对象向主题对象登记,也就是将它加入到主题对象的聚集中去。
这时,客户端调用主题的change()方法,改变了主题对象的内部状态。主题对象在状态发生变化时,调用超类的notifyObservers()方法,通知所有登记过的观察者对象
三.推模型和拉模型(拉模型实现实例)
在观察者模式中,又分为推模型和拉模型两种方式。
● 推模型
主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。
● 拉模型
主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。
根据上面的描述,发现前面的例子就是典型的推模型,下面给出一个拉模型的实例。
拉模式的观察者源码:
package com.blankjor.observer1; /**
* 抽象观察者角色
*
* @author Blankjor
*
*/
public interface Observer {
/**
* 传入主题,获取中的对象
* @param subject
*/
void update(Subject subject); String getName();
} package com.blankjor.observer1; /**
* @desc 具体观察者
* @author Blankjor
* @date 2017年5月13日 下午5:11:52
*/
public class ConcreteObserver implements Observer { private String name;
private String state; public ConcreteObserver(String name) {
this.name = name;
} public String getState() {
return state;
} public void setState(String state) {
this.state = state;
} @Override
public String getName() {
return name;
} @Override
public void update(Subject subject) {
// 主动去主题里拿数据
state = ((ConcreteSubject) subject).getState();
System.out.println(getName() + "观察者状态更新为:" + state);
} } package com.blankjor.observer1; import java.util.ArrayList;
import java.util.List; /**
* 抽象主题角色类
*
* @author aibaibai
*
*/
public abstract class Subject {
/**
* 保存观察者的容器
*/
private List<Observer> list = new ArrayList<Observer>(); /**
* 注册观察者
*/
public void register(Observer o) {
list.add(o);
System.out.println("增加了一个观察者:" + o.getName());
} /**
* 移除观察者
*
* @param o
*/
public void remove(Observer o) {
System.out.println("移除了一个观察者:" + o.getName());
list.remove(o);
} /**
* 通知观察者
*
* @param newState
*/
public void nodifyObservers() {
for (Observer observer : list) {
observer.update(this);
}
}
} package com.blankjor.observer1; /**
* 具体主题角色
*
* @author aibaibai
*
*/
public class ConcreteSubject extends Subject {
/**
* 状态
*/
private String state; public String getState() {
return state;
} public void change(String newState) {
state = newState;
System.out.println("状态变为:" + newState);
System.out.println("开始通知观察者...");
this.nodifyObservers();
} } package com.blankjor.observer1; /**
* @desc 测试观察者模式(拉模式)
* @author Blankjor
* @date 2017年5月13日 下午5:18:30
*/
public class MainTest {
public static void main(String[] args) {
Observer o1 = new ConcreteObserver("o1");
Observer o2 = new ConcreteObserver("o2");
Observer o3 = new ConcreteObserver("o3");
ConcreteSubject csj = new ConcreteSubject();
csj.register(o1);
csj.register(o2);
csj.register(o3);
csj.remove(o2);
csj.change("new State!");
}
}
测试结果:
两种模式的比较
■ 推模型是假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。
■ 推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。
四.JAVA提供的对观察者模式的支持
在JAVA语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。
Observer接口
这个接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。
package java.util; /**
* A class can implement the <code>Observer</code> interface when it
* wants to be informed of changes in observable objects.
*
* @author Chris Warth
* @see java.util.Observable
* @since JDK1.0
*/
public interface Observer { *
* @param o the observable object.
* @param arg an argument passed to the <code>notifyObservers</code>
* method.
*/
void update(Observable o, Object arg);
}
Observable类
被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。
package java.util; /**
* This class represents an observable object, or "data"
* in the model-view paradigm. It can be subclassed to represent an
* object that the application wants to have observed.
* <p>
* An observable object can have one or more observers. An observer
* may be any object that implements interface <tt>Observer</tt>. After an
* observable instance changes, an application calling the
* <code>Observable</code>'s <code>notifyObservers</code> method
* causes all of its observers to be notified of the change by a call
* to their <code>update</code> method.
* <p>
* The order in which notifications will be delivered is unspecified.
* The default implementation provided in the Observable class will
* notify Observers in the order in which they registered interest, but
* subclasses may change this order, use no guaranteed order, deliver
* notifications on separate threads, or may guarantee that their
* subclass follows this order, as they choose.
* <p>
* Note that this notification mechanism has nothing to do with threads
* and is completely separate from the <tt>wait</tt> and <tt>notify</tt>
* mechanism of class <tt>Object</tt>.
* <p>
* When an observable object is newly created, its set of observers is
* empty. Two observers are considered the same if and only if the
* <tt>equals</tt> method returns true for them.
*/
public class Observable {
private boolean changed = false;
private Vector<Observer> obs; /** Construct an Observable with zero Observers. */ public Observable() {
obs = new Vector<>();
} public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
} public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
} public void notifyObservers() {
notifyObservers(null);
} public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal; synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
} for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
} public synchronized void deleteObservers() {
obs.removeAllElements();
} protected synchronized void setChanged() {
changed = true;
} protected synchronized void clearChanged() {
changed = false;
} public synchronized boolean hasChanged() {
return changed;
} public synchronized int countObservers() {
return obs.size();
}
}
这个类代表一个被观察者对象,有时称之为主题对象。一个被观察者对象可以有数个观察者对象,每个观察者对象都是实现Observer接口的对象。在被观察者发生变化时,会调用Observable的notifyObservers()方法,此方法调用所有的具体观察者的update()方法,从而使所有的观察者都被通知更新自己。
五.使用JAVA对观察者模式的支持(自带推模式实现实例)
这里给出一个非常简单的例子,说明怎样使用JAVA所提供的对观察者模式的支持。在这个例子中,被观察对象叫做Watched;而观察者对象叫做Watcher。Watched对象继承自java.util.Observable类;而Watcher对象实现了java.util.Observer接口。另外有一个Test类扮演客户端角色。
package com.blankjor.observer2; import java.util.Observable;
import java.util.Observer; /**
* @desc 具体观察者
* @author Blankjor
* @date 2017年5月13日 下午6:00:08
*/
public class Watcher implements Observer { private String name; public Watcher(String name) {
this.name = name;
} // 另外新添加方式,先思路
public Watcher(Observable o, String name) {
this.name = name;
o.addObserver(this);
} @Override
public void update(Observable o, Object arg) {
System.out.println("观察者" + getName() + "状态已发生改变");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} } package com.blankjor.observer2; import java.util.Observable; /**
* @desc 被观察者
* @author Blankjor
* @date 2017年5月13日 下午5:56:40
*/
public class Watched extends Observable {
private String state = ""; public String getState() {
return state;
} public void setState(String state) {
if (!this.state.equals(state)) {
this.state = state;
setChanged();
}
notifyObservers();
}
} package com.blankjor.observer2; /**
* @desc 测试观察者模式(推模式)
* @author Blankjor
* @date 2017年5月13日 下午5:18:30
*/
public class MainTest {
public static void main(String[] args) {
// 第一种添加方式
Watched wc = new Watched();
Watcher w1 = new Watcher("w1");
Watcher w2 = new Watcher("w2");
wc.addObserver(w1);
wc.addObserver(w2);
// 第二种添加方式
Watcher w3 = new Watcher(wc, "w3");
System.out.println(wc.hasChanged());
wc.setState("ChangeState!");
}
}
测试结果:
MainTest对象首先创建了Watched和Watcher对象。在创建Watcher对象时,将Watched对象作为参数传入;然后调用Watched对象的setState()方法,触发Watched对象的内部状态变化;Watched对象进而通知实现登记过的Watcher对象,也就是调用它的update()方法。
参考:http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html
Java设计模式の观察者模式(推拉模型)的更多相关文章
- java设计模式--观察者模式(Observer)
java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...
- [从源码学设计]蚂蚁金服SOFARegistry之推拉模型
[从源码学设计]蚂蚁金服SOFARegistry之推拉模型 目录 [从源码学设计]蚂蚁金服SOFARegistry之推拉模型 0x00 摘要 0x01 相关概念 1.1 推模型和拉模型 1.1.1 推 ...
- 【设计模式】Java设计模式 - 观察者模式
[设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...
- Java设计模式--观察者模式到监听器
观察者模式是对象的行为模式.又叫做发布-订阅模式.模型-视图模式.源-监听器模式. 抽象主题角色:主题角色将所有对观察者对象的引用到保存在一个集合里,每个主题都可以拥有任意数量的观察者.抽象主题提供一 ...
- JAVA 设计模式 观察者模式
用途 观察者模式 (Observer) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观 ...
- Java设计模式 - 观察者模式
定义 观察者模式属于对象行为型模式. 在对象之间定义一对多的依赖,这样一来当一个对象改变状态,依赖它的对象都会收到通知并自动更新. 优点 1. 主题和观察者之间抽象耦合.无论什么对象主要实现了特定的 ...
- java设计模式--观察者模式和事件监听器模式
观察者模式 观察者模式又称为订阅—发布模式,在此模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来事件 ...
- java设计模式-观察者模式学习
最近学习了设计模式中的观察者模式,在这里记录下学习成果. 观察者模式,个人理解:就是一个一对多模型,一个主体做了事情,其余多个主体都可以观察到.只不过这个主体可以决定谁去观察他,以及做什么事情可以给别 ...
- 我的Java设计模式-观察者模式
相信大家都有看过<喜洋洋与灰太狼>,说的是灰太狼和羊族的"斗争",而每次的结果都是灰太狼一飞冲天,伴随着一句"我还会回来的......".为灰太狼感 ...
随机推荐
- MyBatis中文文档
http://mybatis.github.io/mybatis-3/zh/index.html
- vue.js学习之 跨域请求代理与axios传参
vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{}, ...
- nginx 添加的配置信息
使用logrotate管理Nginx日志配置如下: [root@vm-10-129-93-51 nginx]# vi /etc/logrotate.d/nginx /letv/log/nginx/*. ...
- JS中Document节点总结
document对象是documentHTML的一个实例,也是window对象的一个属性,因此可以将document对象作为一个全局对象来访问. Document节点的子节点可以是DocumentTy ...
- Android 数据存储 之 SQLite数据库详解
. 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/19028665 . SQLiteDataBase示例程序下 ...
- SQL Server 复制:事务发布(读写分离)
一.背景 在复制的运用场景中,事务发布是使用最为广泛的,我遇到这样一个场景:在YangJiaLeClub数据库中有表.存储过程.视图.用户定义函数,需要提供给其它程序读取放入缓存,程序需要比较及时的获 ...
- JAVA单态设计模式
核心--在类的内部把构造器私有化,同时在内部产生对象,并通过类.静态方法(static)返回实例化对象的引用 设计模式是在大量的实践总结和理论化之后优选的代码结果,编程风格,以及解决问题的思考方式 ...
- 最多水容器(M)
题目 给定n个非负整数a 1,a 2,...,a n,其中每个代表坐标(i,a i)处的一个点.绘制n条垂直线,使得线i的两个端点处于(i,a i)和(i,0)处.找到两条线,它们与x轴一起形成一个容 ...
- ACM 第十天
动态规划2 1.树形DP 2.概率DP 3.区间DP 模板 ; len < n; len++) { //操作区间的长度 , j = len; j <= n; i++, j++) { //始 ...
- lintcode-176-图中两个点之间的路线
176-图中两个点之间的路线 给出一张有向图,设计一个算法判断两个点 s 与 t 之间是否存在路线. 样例 如下图: for s = B and t = E, return true for s = ...