码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之观察者模式(Observer)

时间:2014-08-11 20:57:22      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   java   使用   io   数据   for   

1、定义

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并启动更新。

2、问题描述

现在有一个气象站的对象,此对象负责对几个终端输送信息。气象站即可称为主题,而终端即为观察者。气象站和终端是一对多的依赖,当气象站状态改变时,所有终端都会收到通知并启动更新。代码如下:

package observer;
/**
 * 主题
 */
public interface Subject {
    public void registerObServer(Observer o);
    public void removeObServer(Observer o);
    public void notifyObservers();
}
package observer;
/**
 * 观察者
 */
public interface Observer {
    public void update(float temp,float humidity,float pressure);
}
package observer;

import java.util.ArrayList;

public class WeatherData implements Subject{
    
    private ArrayList<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;
    public  WeatherData(){
        observers=new ArrayList<Observer>();
    }
    public void registerObServer(Observer o) {//注册观察者
        observers.add(o);
    }
    @Override
    public void removeObServer(Observer o) {//删除观察者
        observers.remove(o);
    }
    @Override
    public void notifyObservers() {
        for(Observer ob:observers){
            ob.update(temperature, humidity, pressure);
        }
    }
    
    public void measuermentsChanged(){
        notifyObservers();
    }
    
    public float getTemperature() {
        return temperature;
    }
    public void setTemperature(float temperature) {
        this.temperature = temperature;
    }
    public float getHumidity() {
        return humidity;
    }
    public void setHumidity(float humidity) {
        this.humidity = humidity;
    }
    public float getPressure() {
        return pressure;
    }
    public void setPressure(float pressure) {
        this.pressure = pressure;
    }
}
package observer;

public class CurrentConditionsDisplay implements Observer{

    public void update(float temp, float humidity, float pressure) {
        System.out.println("current conditions:"+temp);
    }
}
package observer;

public class WeatherStation {
    public static void main(String a[]){
        WeatherData weatherData=new WeatherData();
        Observer currentDisplay=new CurrentConditionsDisplay();
        weatherData.setHumidity(12);
        weatherData.setPressure(23);
        weatherData.setTemperature(344);
        weatherData.registerObServer(currentDisplay);
        weatherData.measuermentsChanged();
    }
}

以上完美解决了气象台状态改变后改变其他终端数据的问题。但是这种模式是“推”数据方式,将数据从subject推到observer中。但是有时候终端并不需要所有的状态,终端希望自己主动从subject“拉”数据。在java API中有内置的观察者模式。java.util包内包含最基本的Observer接口和Observable类。可以使用推(push)或拉(pull)的方式传送数据。

使用java API的观察者模式的拉模式,代码如下:

package observer;

import java.util.ArrayList;
import java.util.Observable;
/**
 * 集成JAVA API中的Observeable(可观察者)类
 */
public class WeatherData extends Observable{
    
    private float temperature;
    private float humidity;
    private float pressure;
    public  WeatherData(){
    }
    
    public void measurementsChanged(){
        setChanged();//指示状态已经改变
        notifyObservers();//使用拉数据方式
    }
    
    public void setMeasuerments(float temperature,float humidity,float pressure){
        this.temperature=temperature;
        this.humidity=humidity;
        this.pressure=pressure;
        measurementsChanged();
    }
    
    public float getTemperature() {
        return temperature;
    }
    public void setTemperature(float temperature) {
        this.temperature = temperature;
    }
    public float getHumidity() {
        return humidity;
    }
    public void setHumidity(float humidity) {
        this.humidity = humidity;
    }
    public float getPressure() {
        return pressure;
    }
    public void setPressure(float pressure) {
        this.pressure = pressure;
    }
}
package observer;

import java.util.Observable;

public class CurrentConditionsDisplay implements java.util.Observer{
    Observable observable;
    private float temperature;
    private float humidity;
    
    public CurrentConditionsDisplay(Observable observable){
        this.observable=observable;
        observable.addObserver(this);
    }

    @Override
    public void update(Observable obs, Object arg) {
        if(obs instanceof WeatherData){
            WeatherData weatherData=(WeatherData)obs;
            this.temperature=weatherData.getTemperature();
            this.humidity=weatherData.getHumidity();
            System.out.println("Current Conditions:"+this.temperature);
        }
        
    }
}
package observer;

import java.util.Observable;

public class WeatherStation {
    public static void main(String a[]){
        WeatherData weatherData=new WeatherData();
        weatherData.setMeasuerments(12,13, 14);
        java.util.Observer currentDisplay=new CurrentConditionsDisplay(weatherData);
        currentDisplay.update(weatherData, null);
    }
}

java API中的observable使用类而不是接口,不可取。实际中可以自行设计主题和观察者,不使用java api中提供的方式。

在JDK中,Swing大量使用观察者模式,许多GUI框架也是如此。

设计模式之观察者模式(Observer),布布扣,bubuko.com

设计模式之观察者模式(Observer)

标签:style   blog   color   java   使用   io   数据   for   

原文地址:http://www.cnblogs.com/limiracle/p/3905348.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!