Java Observable 模式
一、Observer模式的意图:
在对象的内部状态发生变化时,自动通知外部对象进行响应。
二、Observer模式的构成:
·被观察者:内部状态有可能被改变,而且又需要通知外部的对象
·观察者:需要对内部状态的改变做出响应的对象
三、Observer模式的Java实现:
Java的API中已经为我们提供了Observer模式的实现。具体由java.util.Observable类和java.util.Observer接口完成。
前者有两个重要的方法:
·setChanged:设置内部状态为已改变
·notifyObservers(Object obj):通知观察者所发生的改变,参数obj是一些改变的信息
后者有一个核心方法:
·update(Object obj):相应被观察者的改变,其中obj就是被观察者传递过来的信息,该方法会在notifyObservers被调用时自动调用。
下面是Observer模式的实现过程:
·创建一个被观察者,继承java.util.Observable
·创建一个观察者,实现java.util.Observer接口
· 注册观察着,调用addObserver(Observer observer)
·在被观察者改变对象内部状态的地方,调用setChanged()方法,然后调用notifyObservers(Object)方法,通知被观察者
·在观察者的update(Object)方法中,对改变做出响应。
四、Observer模式的好处:
1.Observer模式的优点:
·被观察者只需要知道谁在观察它,无需知道具体的观察细节
·被观察者一旦发生变化,只需要通过广播的方式告知观察者,至于消息如何到达则不需知道。这样的话无疑消除了被观察者和观察者之间通信的硬编码
·当一个被观察者同时被多个观察着观察时,观察者可以只选择自己感兴趣的事件,而忽略其它的事件
·多个观察者组合起来可以形成一个观察链,如果一旦需要回滚多个操作,此时观察链可以发挥作用
·观察者可以实时对被观察对象的变化做出响应,例如自动告警、中断运行等
2.运用Observer模式可以
·屏蔽线程间的通信机制:例如两个线程之间,主线程可以作为观察者,执行线程是被观察者。彼此之间只知道对方存在,但不知道之间通信的细节
·消除硬编码:如果没有Observer模式,则只能采用回调的模式,或者在代码中显示地调用观察者
·优化异常机制:特别适合在异常发生时向顶层监控,减少try-catch代码量
代码:
- public class Observable {
- private boolean changed = false;
- private Vector obs;
- //创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。
- 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) {
- 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 interface Observer {
- /**
- * This method is called whenever the observed object is changed. An
- * application calls an <tt>Observable</tt> object's
- * <code>notifyObservers</code> method to have all the object's
- * observers notified of the change.
- *
- * @param o the observable object.
- * @param arg an argument passed to the <code>notifyObservers</code>
- * method.
- */
- void update(Observable o, Object arg);
- }
- }
- public class MailObserver implements Observer{
- /**
- * 这个类取名为MailObserver,顾名思义,她是一个用来发送邮件的观察者
- */
- public void update(Observable o, Object arg) {
- System.out.println("发送邮件的观察者已经被执行");
- }
- }
- public class JMSObserver implements Observer{
- public void update(Observable o, Object arg) {
- System.out.println("发送消息给jms服务器的观察者已经被执行");
- }
- }
- public class Subject extends Observable{
- /**
- * 业务方法,一旦执行某个操作,则通知观察者
- */
- public void doBusiness(){
- if (true) {
- super.setChanged();
- }
- notifyObservers("现在还没有的参数");
- }
- public static void main(String [] args) {
- //创建一个被观察者
- Subject subject = new Subject();
- //创建两个观察者
- Observer mailObserver = new MailObserver();
- Observer jmsObserver = new JMSObserver();
- //把两个观察者加到被观察者列表中
- subject.addObserver(mailObserver);
- subject.addObserver(jmsObserver);
- //执行业务操作
- subject.doBusiness();
- }
- }
在spring中使用观察者模式的方法如下
<bean id="mailObserver" class="MailObserver"/>
<bean id="jmsObserver" class="JMSObserver"/>
<bean id="subjectTarget" class="Subject"/>
<bean id="subject"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="subjectTarget"/></property>
<property name="targetMethod"><value>addObserver</value></property>
<property name="arguments">
<list>
<ref bean="mailObserver"/>
<ref bean="jmsObserver"/>
</list>
</property>
</bean>
观察者模式的效果有以下几个优点:
(1)观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者 的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象 化层次。
(2)观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。
观察者模式有下面的一些缺点:
(1)如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
(2)如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察考模式时要特别注意这一点。
(3)如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的
Java Observable 模式的更多相关文章
- 设计模式--观察者模式初探和java Observable模式
初步认识观察者模式 观察者模式又称为发布/订阅(Publish/Subscribe)模式,因此我们可以用报纸期刊的订阅来形象的说明: 报社方负责出版报纸. 你订阅了该报社的报纸,那么只要报社发布了新报 ...
- 《JAVA与模式》之观察者模式
转自:http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html 在阎宏博士的<JAVA与模式>一书中开头是这样 ...
- <代码整洁之道>、<java与模式>、<head first设计模式>读书笔记集合
一.前言 几个月前的看书笔记 ...
- 《JAVA与模式》之观察者模式(转载)
<JAVA与模式>之观察者模式(转载) 原文链接:http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html ...
- java future模式 所线程实现异步调用(转载
java future模式 所线程实现异步调用(转载) 在多线程交互的中2,经常有一个线程需要得到另个一线程的计算结果,我们常用的是Future异步模式来加以解决.Future顾名思意,有点像期货市场 ...
- JAVA的模式对话框和非模式对话框
周末的时候,一位网友让我帮他把他的无模式对话框改成有模式对话框. 界面是由swing制作的,都是JFrame,我从来没有接触过swing编程.大致的代码还是看的懂,很多都和C#很相似. 然后就去查资料 ...
- java工厂模式
(1)概念大白话:java工厂模式就是客户端(main函数)要创建对象觉得麻烦就让另外一个叫工厂的类帮它创建,然后自己每次要创建对象就叫工厂帮它弄,举个例子,在没有工厂这个"手下" ...
- 《JAVA与模式》之单例模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述单例模式的: 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的 ...
- Java代理模式
java代理模式及动态代理类 1. 代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...
随机推荐
- 模拟+思维 HDOJ 5319 Painter
题目传送门 /* 题意:刷墙,斜45度刷红色或蓝色,相交的成绿色,每次刷的是连续的一段,知道最终结果,问最少刷几次 模拟+思维:模拟能做,网上有更巧妙地做法,只要前一个不是一样的必然要刷一次,保证是最 ...
- 两台笔记本搭建openvswitch网络
环境说明: 笔记本A.B均运行Ubuntu 14.04,两台笔记本通过无线网卡上网,用一根网线连接两台笔记本的有线网卡. 网络拓扑: 其中,vm1 vm2 S1位于笔记本A,vm3 vm4 S2位于笔 ...
- hdu 3853 LOOPS(基础DP求期望)
题目大意 有一个人被困在一个 R*C(2<=R,C<=1000) 的迷宫中,起初他在 (1,1) 这个点,迷宫的出口是 (R,C).在迷宫的每一个格子中,他能花费 2 个魔法值开启传送通道 ...
- http和socket通信的区别
应用层:HTTP协议(基于传输层的TCP协议,主要解决如何包装数据) 传输层: TCP协议(基于网络层的IP协议).TPC/IP协议(主要解决数据如何在网络中传输) 网络层: IP 协议 socket ...
- servlet学习笔记二
Servlet主要内容: 1)表单处理 2)乱码问题 3)页面跳转 4)生命周期 一.表单处理 Servlet获取表单数据 request.getParameter():通过表单参数名获取参数值 re ...
- iOS tintColor解析
在UIView中一个相对来说比较小的属性,tintColor属性是相当的强大.今天我们就来看看如何使用他,包含使用tint color进行着色标准控件.我们自定义控件甚至重新着色图像. 本章的实例程序 ...
- 很赞的MathJax
一直想在网页上放进LaTeX布局,但由于是要发布在SAE上,因此有很多的限制. 然后在这儿发现了这个好东东,MathJax,非常方便,JS直接可以外链. 通过它,我编辑了这个页面,看起来很不错哦.
- 汇编与C语言混合 实现的从小到大的冒泡排序
汇编实现的从小到大的冒泡排序 主函数由C语言实现,sort函数用汇编语言写 #include <stdio.h> int buffer[256]; //数据缓冲区 int ...
- VMware VMware各版本
VMware各版本 一.VMware vSphere5: VMware vSphere5 取代原 VMware ESX 二.VMware ESXI/VMware Citrix/VMware XenS ...
- 数组工具类 - ArrayUtil.java
数组工具类,提供数组.对象之间转换的方法. 源码如下:(点击下载 - ArrayUtil.java .commons-lang-2.6.jar) import java.lang.reflect.Ar ...