Head First从气象观测分析——观察者模式

本文目录

1. 这篇博客的由来

观察者模式是Head First 设计模式中的第二种设计模式,书中以气象观测为案例贯穿观察者模式。下面我们来熟悉一下观察者模式吧。

2. 观察者模式介绍
  1. 观察者模式的定义

    定义对象间的一种一对多 的依赖关 系,让多个观察者同时监听某一个主题现象,当一个对象的状态发生改变时,会通知所有观察者对象,所有依赖于它的对象都得到通知并被自动更新。

  2. UML图
    观察者模式uml图

  3. 观察者模式的基本角色

     - Subject接口(被观察者接口)(确定被观察者对象的基本行为,注册观察者、移除观察者、通知消息)		 
    - ConcreteSubject类(被观察者实现类)
    -  Observer(观察者接口)(更新行为)
    - ConcreteObserver(被观察者实现类)
    
3. 从气象观测分析观察者模式
  • 需求描述

在这里插入图片描述

  • 分析实现
    从上图可以知道,我们事先了解气象站将会给我们什么参数,每当气象站的参数发生改变时,我们的显示装置也要对应发生改变,我们可以拥有多个显示装置(公告板),但每个显示装置的具体显示可能不同。

下面是总体实现图
在这里插入图片描述
从上面可以看到,被观察者必须拥有三个方法(加入观察者,移除观察者,通知观察者),被观察者拥有更新数据的方法,因为这里的展示可能不同,所以抽离了一个接口专门做展示功能。

4. 分析气象观测案例的角色

Subject接口实现(被观察者接口类)

package subject;
import observer.Observer;
public interface Subject {
	public void registerObserver(Observer o);
	public void removeObserver(Observer o);
	public void notifyObserver();
}

WeatherData类(被观察者实现类)

package subject.impl;

import java.util.ArrayList;

import observer.Observer;
import subject.Subject;

/**
 * @author wuliz
 *	主题类
 */
public class WeatherData implements Subject {
	private ArrayList observers;
	private float temperature;
	private float humidity;
	private float pressure;
	
	/**
	 * 初始化容器
	 */
	public WeatherData(){
		observers = new ArrayList();
	}
	
	
	/* (non-Javadoc)
	 * @see subject.Subject#notifyObserver()
	 */
	@Override
	public void notifyObserver() {
		// TODO Auto-generated method stub
		for(int i=0;i<observers.size();i++){
			Observer o = (Observer)observers.get(i);
			o.update(temperature, humidity, pressure);
		}
	}

	@Override
	public void registerObserver(Observer o) {
		// TODO Auto-generated method stub
		observers.add(o);
	}

	@Override
	public void removeObserver(Observer o) {
		// TODO Auto-generated method stub
		int i = observers.indexOf(o);
		if(i>=0){
			observers.remove(i);	
		}
		
	}
	
	/**
	 * @param temp
	 * @param humidity
	 * @param pressure
	 */
	public void setMeasurements(float temp,float humidity,float pressure){
		this.temperature=temp;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
		
	}
	
	public void measurementsChanged(){
		notifyObserver();
	}
}

Observer接口(观察者接口)

package observer;

public interface Observer {
	public void update(float temp,float humidity,float pressure);
}

ConcreteObserver类(观察者实现类)

package observer.impl;

import observer.Observer;
import show.DisplayElement;
import subject.Subject;
public class CurrentConditionDisplay implements Observer, DisplayElement {
	private float temperature;
	private float humidity;
	private Subject weatherData;
	
	
	public CurrentConditionDisplay(Subject weatherData){
		this.weatherData=weatherData;
		this.weatherData.registerObserver(this);
	}
	
	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("温度 :"+temperature+",湿度:"+humidity);
	}
	
	@Override
	public void update(float temp, float humidity, float pressure) {
		// TODO Auto-generated method stub
		this.temperature = temp;
		this.humidity = humidity;
		display();
	}

}

5.对比java实现的观察者模式

除我们自己实现的观察者模式,还可以了解一下java jdk 自带实现的观察者模式。
java.util.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();
    }
}

java.util.Observer接口


package java.util;

public interface Observer {
  
    void update(Observable o, Object arg);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值