`

观察者模式梳理二

阅读更多

顾名思义就是观察者从被观察者身上拉取自己需要的数据!

类结构图同拉的方式,不过具体代码上会有点区别!
本案中被观察者接口和观察者接口我们采用的是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类...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    观察者模式 状态模式 策略模式 模板方法模式 访问者模式 设计案例 UML 架构 系统架构能力 基本理论 扩展性设计 可用性设计 可靠性设计 一致性设计 负载均衡设计 过载保护设计 协议设计 二进制协议...

    传智播客扫地僧视频讲义源码

    本教程共分为5个部分,第一部分是C语言提高部分,第二部分为C++基础部分,第三部分为C++进阶部分,第四部分为C、C++及数据结构基础部分,第五部分为C_C++与设计模式基础,内容非常详细. 第一部分 C语言提高部分目录...

    Unity游戏开发高级教程 第一部分 [MP4] (9.42G)

    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 ...

    leetcode分类-Java-grammar1:java学习资料,使用技巧,各方面应用,基于jdk1.8.151版本之前的总结,各个版本更改

    观察者模式 中介者模式 2018.08.09 更新设计模式 结构型模式 适配器模式 桥接模式, 装饰模式, 外观模式, 享元模式, 代理模式。行为型模式的策略模式。 2018.08.08 更新设计模式 单例,工厂,建造者模式 2018.05....

    中国云计算产业发展白皮书2011.pdf

    作为中国IT产业的观察者和研究者,赛迪顾问充分运用自身的强大资源优势,长期追踪包括云计算在内的中国IT产业发展现状与未来趋势。以标准化、专业化、国际化的定义和方法,结合自身对中国IT产业的深刻理解,为产业链...

    中国云计算产业发展白皮书

    作为中国IT产业的观察者和研究者,赛迪顾问充分运用自身的强大资源优势,长期追踪包括云计算在内的中国IT产业 发展现状与未来趋势。以标准化、专业化、国际化的定义和方法,结合自身对中国IT产业的深刻理解,为产业...

    source-code-study:【通用中】源码学习

    原始学习项目结构,两种方式:不在本项目中,引用项目地址,例如:node....backbone.js以类jq和underscore为基础的mvc框架知识点梳理: (1,MVC框架2,观察者模式以及控制反转) (1,控制反转,依赖注入) (浅谈REST

    数据整理分析方法.docx

    偏差包括很大一类潜在有趣的知识,如分类中的反常实例,模式的例外,观察结果对期望的偏差等,其目的是寻找观察结果与参照量之间有意义的差别。在企业危机管理及其预警中,管理者更感兴趣的是那些意外规则。意外规则...

    现代智能保险科技报告.pptx

    Experts IDI 行业深入挖掘阶段: 详细针对国内保险科技发展历程、概念、 宏观环境、服务流程构成和模式、企业经 营状况、企业战略、发展趋势等细节问题, 进行深入挖掘,听取来自行业第一线工作 者和企业高管对保险...

    认知、思维、智能的区别.docx

    认知是初始阶段,它是人类通过观察获得数据、信息、知识、模式、状态、趋势的第一步,通过认知,人们从自然和社会交互中形成了不同的概念(名),提炼出差异的规律(道),梳理为多种工具和方法。认知是数据和信息...

    网络安全数据可视化概述.docx

    并提供友好的交互手段,建立人与数据之间的图像通信,借助人们的视觉处理能力观察网络安全数据中隐含的信息,以进一步提高分析人员的感知、分析和理解网络安全问题网络安全数据可视化概述全文共6页,当前为第2页。...

    BPS开发指南.chm

    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开发透视图 ...

Global site tag (gtag.js) - Google Analytics