`

观察者模式梳理二

阅读更多

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

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

 

 

分享到:
评论

相关推荐

    android框架设计模式和设计原则

    3. **观察者模式**:Android中的BroadcastReceiver就是观察者模式的实例,用于组件间的通信,当某个事件发生时,观察者会收到通知并做出相应。 4. **适配器模式**:ListView、RecyclerView等控件的Adapter就是...

    软件秘籍--设计模式那点事随书光盘

    行为型模式如策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式和解释器模式,关注的是对象之间的交互和职责分配。 案例源码部分则为读者提供了实际操作的...

    深入浅出设计模式之附录A

    - **观察者模式**:定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 ### 三、附录A可能涵盖的内容 由于题目中提到的是附录部分,这部分内容往往是对...

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

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

    C/C++设计模式基础教程

    - **观察者模式**:当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 - **迭代器模式**:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。 - **访问者...

    程序员考试关键考点梳理与考前集训(PDG)

    7. **软件设计与分析**:理解面向对象编程的概念,如封装、继承、多态,以及设计模式(如单例模式、工厂模式、观察者模式)的应用。了解软件复杂度度量和性能优化策略。 8. **软件测试**:掌握软件测试的基本理论,...

    java与模式 源代码

    设计模式包括创建型模式(如单例、工厂方法、抽象工厂)、结构型模式(如适配器、装饰器、代理)和行为型模式(如策略、观察者、责任链)等。 2. **Java编程语言**:Java是一种广泛使用的面向对象的编程语言,以其...

    JAVA设计模式整理(有部分参考代码)

    23. **观察者模式**:定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 这个压缩包中的文件很可能是针对以上各个设计模式的详细讲解和代码示例,对于学习...

    23种设计模式整理(很全).pdf.zip

    - 观察者模式(Observer):定义对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 - 状态模式(State):允许对象在其内部状态改变时改变其行为,对象看起来似乎...

    完美模式设计指南(UML)

    这些模式在帮助开发人员避免重复造轮子的同时,还能提高软件的可读性和可维护性,如工厂模式用于创建对象,单例模式保证类只有一个实例,观察者模式用于对象间的事件通知机制等。 《指南》的目标读者可能是软件...

    24种设计模式介绍与6大设计原则

    16. 观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 17. 责任链模式(Chain of Responsibility Pattern):为解除...

    CC++与设计模式基础课程_讲义

    - **观察者模式**:当对象的状态发生改变时通知所有观察者,使他们能够自动更新。 以上所述的设计模式是C/C++与设计模式基础课程中的重要内容,通过对这些模式的学习和实践,开发者可以显著提高软件设计的能力和...

    ASP.NET 设计模式

    - 深入讲解了在业务逻辑层中使用的具体设计模式,例如命令模式、观察者模式等。 - 提供了实际案例研究,展示如何在业务逻辑层中正确应用这些模式。 - **第6章:服务层**: - 介绍服务层的概念以及如何使用面向...

    Uml和模式应用 配套视频笔记1

    6. **模式应用**:在软件设计中,模式是一种解决常见问题的模板,如工厂模式、观察者模式等。理解和应用设计模式可以提高代码的可读性、可维护性和复用性。在视频笔记中,可能会讲解如何在实际项目中运用这些模式。 ...

    高职院校Java程序设计课程中设计模式的教学设计与实施.pdf

    5. 设计模式的类别包括但不限于工厂模式、单例模式、策略模式、观察者模式、装饰模式等,这些都是程序员应当熟练掌握的模式。 6. 文档提到了UML(统一建模语言)和API(应用程序编程接口)的重要性,这两者都是软件...

    java设计模式考试题.pdf

    16. **观察者模式**:观看者角色被动更新(A),被观看者通知更新(B),但观看者不应改变被观看者状态(C错误)。 17. **里式代换原则**:违反该原则时,可以通过创建新抽象类(A),委派关系(B),或者区分IS-a...

    面向对象与设计模式基础笔记

    - **观察者模式**:定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 - **策略模式**:定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换。 - **...

Global site tag (gtag.js) - Google Analytics