顾名思义就是观察者从被观察者身上拉取自己需要的数据!
类结构图同拉的方式,不过具体代码上会有点区别!
本案中被观察者接口和观察者接口我们采用的是JDK自带的API来写!里面已经考虑了多并发的情况。但是他的观察者是一个类,又因为java是单继承的,所以在这点稍微有点不好!但是想把一些基础的功能搞定的话,必须使用类来操作。矛盾啊!
被观察者的实现
package com.alibaba.test.observer.api;
import java.util.Observable;
public class WeatherData2 extends Observable {
private float temperature;
private float humidity;
private float pressure;
public void setMeaturements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
changed();
}
public void changed() {
setChanged(); //这步很有必要,这样我们就可以有更多的弹性,可以适当的通知观察者,比如说在10秒通知一次,那么就不需要每次实时很敏感的通知!
// if time & 10 == 0 {....}
notifyObservers();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
//测试代码,这里可以清晰的看到,没有建立观察者和被观察者之间的关系,两者之间关系的确立时在观察者内!具体看观察者的代码!
public static void main(String[] args) {
WeatherData2 data2 = new WeatherData2();
new BObserver(data2);
data2.setMeaturements(0.6f, 0.9f, 2.0f);
}
}
观察者的实现:
package com.alibaba.test.observer.api;
import java.util.Observable;
import java.util.Observer;
import com.alibaba.test.observer.DisplayMent;
public class BObserver implements Observer, DisplayMent {
private float t;
private float h;
private Observable o;
//这里将自己加入了观察者的队列中!
public BObserver(Observable o) {
this.o = o;
this.o.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
//对于被观察者对象的数据封装起来,观察者自己主动获取需要的数据,如果做的更好的话,可以再建立一个上下文来封装数据
if (o instanceof WeatherData2) {
//这点也非常重要,我们可以利用JDK的观察者模式添加多个观察者,然后通过判断的方式来获取自己需要的数据,但是又会有一个问题,被观察对象是继承了Observer,那么在有多个不同类型或者是纬度的被观察者时,会造成一定的性能问题。故在某些情况下有必要做下区分!或者自己重写JDK的Observer
WeatherData2 temp = (WeatherData2) o;
this.t = temp.getTemperature();
this.h = temp.getHumidity();
display();
}
}
@Override
public void display() {
System.out.println("the temperature is:" + t + " the humidity is :" + h);
}
}
问题;
JDK的 Observer内部实现是vector + syncd的方式,防止多并发,有必要改写下!
可以看下他的通知所有观察者的实现:
public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal; //这里采用的是对象拷贝的方式
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary code while holding its own Monitor.
* The code where we extract each Observable from
* the Vector and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
采用JDK版本的缺陷:
1. 主题也就是被观察者是一个类,在JAVA中是单继承的方式,如果继承了这个类,就无法继承其他的方式
2. 也因为是类,并且setChanged()是priotected 那么就必须采用继承的方式,违法的多用组合,少用继承的原则!
好的做法是重写这个observer,因为这个类出现的比较早,在考虑多线程方面,采用的都是早期的类,可以换用JDK5后的并发包!
要点总结:
1.被观察者对象持有观察者的对象集合
2.被观察者拥有添加,删除,通知所有观察者对象的行为
3.方式有推和拉两种,两者的本质区别是一种把添加观察对象的操作在被观察者这边,另一种是在观察者对象将自己添加到被观察者对象集合中,本质上是一样的
4.有多个观察者时,不需要依赖特定的顺序
使用场景:
图形界面编程的 SWING AWT GWT等,触发监听器!
分享到:
相关推荐
本文来自51cto,文章主要介绍了策略模式、观察者模式、装饰模式、单例模式以及饿汉模式等的相关内容。泛化=实现>组合>聚合>关联>依赖一个人(Person)可以买车(car)和房子(House),那么就可以称:Person类依赖于Car类...
观察者模式 状态模式 策略模式 模板方法模式 访问者模式 设计案例 UML 架构 系统架构能力 基本理论 扩展性设计 可用性设计 可靠性设计 一致性设计 负载均衡设计 过载保护设计 协议设计 二进制协议...
本教程共分为5个部分,第一部分是C语言提高部分,第二部分为C++基础部分,第三部分为C++进阶部分,第四部分为C、C++及数据结构基础部分,第五部分为C_C++与设计模式基础,内容非常详细. 第一部分 C语言提高部分目录...
7.3观察者模式和代理模式(2); C. B/ {" F1 W/ C 8.3观察者模式和代理模式(3)$ Z( }% \4 M( L$ D- Y$ X3 M 9.4 中介者建造者模式(1)7 M+ {$ r, }: j3 y8 K- e8 W) _/ W9 O) z 10.4 中介者建造者模式(2)" T+ r( s4 V6 ...
观察者模式 中介者模式 2018.08.09 更新设计模式 结构型模式 适配器模式 桥接模式, 装饰模式, 外观模式, 享元模式, 代理模式。行为型模式的策略模式。 2018.08.08 更新设计模式 单例,工厂,建造者模式 2018.05....
作为中国IT产业的观察者和研究者,赛迪顾问充分运用自身的强大资源优势,长期追踪包括云计算在内的中国IT产业发展现状与未来趋势。以标准化、专业化、国际化的定义和方法,结合自身对中国IT产业的深刻理解,为产业链...
作为中国IT产业的观察者和研究者,赛迪顾问充分运用自身的强大资源优势,长期追踪包括云计算在内的中国IT产业 发展现状与未来趋势。以标准化、专业化、国际化的定义和方法,结合自身对中国IT产业的深刻理解,为产业...
原始学习项目结构,两种方式:不在本项目中,引用项目地址,例如:node....backbone.js以类jq和underscore为基础的mvc框架知识点梳理: (1,MVC框架2,观察者模式以及控制反转) (1,控制反转,依赖注入) (浅谈REST
偏差包括很大一类潜在有趣的知识,如分类中的反常实例,模式的例外,观察结果对期望的偏差等,其目的是寻找观察结果与参照量之间有意义的差别。在企业危机管理及其预警中,管理者更感兴趣的是那些意外规则。意外规则...
Experts IDI 行业深入挖掘阶段: 详细针对国内保险科技发展历程、概念、 宏观环境、服务流程构成和模式、企业经 营状况、企业战略、发展趋势等细节问题, 进行深入挖掘,听取来自行业第一线工作 者和企业高管对保险...
认知是初始阶段,它是人类通过观察获得数据、信息、知识、模式、状态、趋势的第一步,通过认知,人们从自然和社会交互中形成了不同的概念(名),提炼出差异的规律(道),梳理为多种工具和方法。认知是数据和信息...
并提供友好的交互手段,建立人与数据之间的图像通信,借助人们的视觉处理能力观察网络安全数据中隐含的信息,以进一步提高分析人员的感知、分析和理解网络安全问题网络安全数据可视化概述全文共6页,当前为第2页。...
03.01 流程梳理 03.02 流程建模模拟 03.03 业务实现 03.04 开发测试 03.05 流程发布 03.06 运行管理监控 03.07 流程分析 03.08 流程调整 04 BPS使用参考 04.01 BPS Studio概述 04.01.01 BPS开发透视图 ...