您的位置:首页 > 其它

设计模式-2-观察者模式(2)

2016-04-10 21:29 387 查看
1.观察者模式中的拉和推的介绍

观察者获取主题的通知有两种方式,一种是主题主动更新后将全部的信息发送给观察者(push),另一种是观察者自己从主题哪里选择自己需要的信息获取(pull)。(推的方式被认为更正确)

java内置的观察者模式支持推和拉两种方式,一拉的方式代码举例。

2.java内置的观察者模式如何运作---代码示例“拉”的方式

--------java内置的Observable抽象类-----------

public class Observable {

    private boolean changed = false;

    private Vector<Observer> 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 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();

    }

}

--------接口Display -----------

package com.lxt.pattern.observer.javaObserver;

public interface DisplayElement {
void dispaly();

}

[b]--------WeatherData继承内置Observable类 -----------
[/b]

public class WeatherData extends Observable{
private float temperature;
private float humidity;
private float pressure;
/**
* 拉的方式需要观察者获取主题信息 
* 用到get方法
* @return
*/
public float getTemperature() {
return temperature;
}

public float getHumidity() {
return humidity;
}

public float getPressure() {
return pressure;
}

public WeatherData(){

}
public void measurementChanged(){
//改变状态  让更新更有弹性   可以设置更新的时间条件。。。
setChanged();
//没有传递参数  表示用啦的方式
notifyObservers();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}

}

[b][b]--------三个观察者类-----------
[/b][/b]

1.

package com.lxt.pattern.observer.javaObserver;

import java.util.Observable;

import java.util.Observer;

public class StatisticDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
Observable observable;

public StatisticDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void dispaly() {
// TODO Auto-generated method stub
System.out.println("Statistic conditions:"+temperature
+" "+humidity 
);
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof WeatherData ){
WeatherData weatherData = (WeatherData)o;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
dispaly();
}

}

}

2.

package com.lxt.pattern.observer.javaObserver;

import java.util.Observable;

import java.util.Observer;

public class ForeastDisplay implements Observer,DisplayElement{
private float pressure;

Observable observable;

public ForeastDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void dispaly() {
// TODO Auto-generated method stub
System.out.println("Foreast conditions:"+pressure

);
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof WeatherData ){
WeatherData weatherData = (WeatherData)o;
this.pressure = weatherData.getPressure();

dispaly();
}

}

}

3.

package com.lxt.pattern.observer.javaObserver;

import java.util.Observable;

import java.util.Observer;

public class CurrentCondionsDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
Observable observable;

public CurrentCondionsDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void dispaly() {
// TODO Auto-generated method stub
System.out.println("Current conditions:"+temperature
+" "+humidity 
);
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof WeatherData ){
WeatherData weatherData = (WeatherData)o;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
dispaly();
}

}

}

[b][/b]

[b][b]--------测试类-----------
[/b][/b]

package com.lxt.pattern.observer.javaObserver;

public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();

CurrentCondionsDisplay condionsDisplay = 
new CurrentCondionsDisplay(weatherData);
StatisticDisplay statisticsDisplay = 
new StatisticDisplay(weatherData);
ForeastDisplay foreastDisplay = 
new ForeastDisplay(weatherData);
System.out.println("只是为输出内容.......");
weatherData.setMeasurements(80, 70, 90);
weatherData.setMeasurements(90, 70, 22);
weatherData.setMeasurements(45, 22, 11);
}

}

[b][b]--------控制台输出结果-----------[/b][/b]

只是为输出内容.......

Foreast conditions:90.0

Statistic conditions:80.0 70.0

Current conditions:80.0 70.0

Foreast conditions:22.0

Statistic conditions:90.0 70.0

Current conditions:90.0 70.0

Foreast conditions:11.0

Statistic conditions:45.0 22.0

Current conditions:45.0 22.0

[b][b]3.java内置观察者模式的黑暗面----不足[/b][/b]

1)java.util.Observable是一个类
 即主题是一个类,而不一个可实现的接口,限制使用和复用

2)必须设计一个类来继承Observable,如果想实现具有该类和另一个超类的行为就陷入了困境,java不支持多继承。

3)没有 Observable接口,无法建立自己的实现和java内置的Observer
Api搭配使用

4)查看源码可知,setChanged被保护起来了,意味着如果不继承该类则无法创建Observable实例并组合到自己的对象中去。违反“多用组合,少用继承”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: