设计模式二 观察者模式


一 新的设计原则

为对象之间的松耦合而努力


二 观察者设计模式

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

三 问题描述

问题描述:当天气检测到温度、水分等有变化时,会自动更新温度显示板,水分显示板上的数据。


主要思想:

把需要显示数据的模块都当做观察者,提供数据的模块当做主题,那么,当主题有数据更新后,观察者怎么自动显示最新的数据了,在观察者初始化的时候,把该观察者注册到

主题中,当主题有新的数据更新时,只需要遍历已经注册观察者的update方法.


四 代码

主题接口:

public interface Subject {
 void registerObserver(Observer o);
 void removeObserver(Observer o);
 void notifyObserver();
}


WeatherData

public class WeatherData implements Subject {
	private List<Observer> observerList;
	private float temp;
	private float humidity;
	private float pressure;
	
	public WeatherData(){
		observerList = new ArrayList<Observer>();
	}
   //注册观察者
	@Override
	public void registerObserver(Observer o) {
		// TODO Auto-generated method stub
	       observerList.add(o);
	}
    //移除观察者
	@Override
	public void removeObserver(Observer o) {
		// TODO Auto-generated method stub
		//查询此对象是否注册
		int i = observerList.indexOf(o);
		if(i>0){
			observerList.remove(o);
		}
	}
    //通知观察者
	@Override
	public void notifyObserver() {
		// TODO Auto-generated method stub
		for(Observer observer:observerList){
			observer.update(temp, humidity, pressure);
		}

	}
	
   public void measurement(){
	   notifyObserver();
   }
   //测试写的set方法
   public void setMeasurement(float temp,float humidity,float pressure){
	   this.temp=temp;
	   this.humidity=humidity;
	   this.pressure=pressure;
	   notifyObserver();
   }
}

观察者接口:
public interface Observer {
 void update(float temp,float humidity,float pressure);
}


观察者实现

public class ForecastDisplay implements Observer, DisplayElement {
	private float temp;
	private float humidity;
	private float pressure;
	private Subject weatherData;
	public ForecastDisplay(Subject weatherData){
		//注册观察者
		this.weatherData=weatherData;
		this.weatherData.registerObserver(this);
	}

	@Override
	public void update(float temp, float humidity, float pressure) {
		// TODO Auto-generated method stub
     this.temp=temp;
     this.humidity=humidity;
     this.pressure=pressure;
     display();
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("ForecastDisplay:" +temp+"F degree"+humidity+"P pressure"+pressure);
	}
}

测试:

public class WeatherStation {

	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
		CurrentConditionalDisplay currentConditionalDisplay = new CurrentConditionalDisplay(weatherData);
		weatherData.setMeasurement(12.3f, 20.5f, 30.2f);
	}
}


Java内置的观察者设计模式使用

java.util.Observable 类作为主题   java.util.Observer作为观察者接口

/**
 * 继承java内部的提供的观察者模式实现观察者
 *
 */
public class WeatherData extends Observable {
	private float temp;
	private float humidity;
	private float pressure;
	
	
	public void measurementsChanged(){
		//调用setChanged的原因是,notifyObservers会有一个标志位表示通不通知观察者
		setChanged();
		notifyObservers();
	}
	
	//测试写的set方法
	   public void setMeasurement(float temp,float humidity,float pressure){
		   this.temp=temp;
		   this.humidity=humidity;
		   this.pressure=pressure;
		   measurementsChanged();
	   }

	public float getTemp() {
		return temp;
	}

	public float getHumidity() {
		return humidity;
	}

	public float getPressure() {
		return pressure;
	}
}

public class CurrentConditionalsDisplay implements Observer ,DisplayElement{
	
	private float temp;
	private float humidity;
	private Observable observable;
	
	public CurrentConditionalsDisplay(Observable o){
		//注册观察者
		this.observable  = o;
		this.observable.addObserver(this);
	}

	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		//可以判断是哪个那个主题
		if(o instanceof WeatherData){
			WeatherData weatherData = (WeatherData)o;
			this.temp=weatherData.getTemp();
			this.humidity=weatherData.getHumidity();
		}
        display();
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("CurrentConditions"+this.temp+"humidity"+this.humidity);
	}

}

测试:

public class WeatherStation {
 public static void main(String[] args) {
	WeatherData weatherData = new WeatherData();
	CurrentConditionalsDisplay currentConditionalsDisplay = new CurrentConditionalsDisplay(weatherData);
	weatherData.setMeasurement(32.1f, 23.5f, 20.6f);
}
}




猜你喜欢

转载自blog.csdn.net/strong_yu/article/details/70800318