the observer pattern 观察者模式

 

 keeping your objects in the know

 

类似于报纸发行商和订阅者之间的关系
publisher + subscribers = observer pattern
我们称发行者为subject,订阅者为observers

 

1.subject对象管理一些数据
2.当subject对象中的数据改变时,通知observers
3.注册到subject的observers接收更新,当subject中的数据改变

 

观察者模式定义一个一对多的关系,当那个一个对象状态改变,附属的多个对象会接收到通知然后自动修改自己的状态

观察者模式提供subject和observer之间的松耦合
好处:
1.subject只知道observer实现了一个特定接口
2.很容易添加一个新的observer
3.添加新的observer不需要修改subject
4.重用subject,observer很方便,他们之间独立存在
5.对于subject,observer的修改不会影响到对方

 

例子:

一个天气采集系统,参数有温度,湿度以及气压,有多个显示系统,当3个参数改变的时候,显示系统都要相应的修改

一般情况的设计:

public calss WeatherData{
	//instance variable decalrations
	public void measurementsChanged(){
		float temp = getTemperature();
		float pressure = gethumidity();
		float pressure = getPressure();

		currentConditionsDisplay.update(temp,humidity,pressure);
		statisticsDisplay.update(temp,humidity,pressure);
	}
	//other weatherData methods here
}

 但是我们每次新添加一个显示系统需要修改代码,不能在运行时添加或者删除某个显示系统,采用观察者模式修改如下:

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

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

}

public class WeatherData implements Subject
{
	private ArrayList observers;
	private float temperature;
	private float humidity;
	private float pressure;

	public WeatherData(){
		observer = new ArrayList();
	}

	public void registerobserver(Observer o){
		observers.add(o);
	}

	public void removeObserver(Observer o){
		int i = observers.indexOf(o);
		if(i>=0)
			observers.remove(o);
	}

	public void notifyObservers(){
		for(int i=0;i<observers.size();i++){
			Observer observer = (Observer)observers.get(i);
			observer.update(temperature,humidity,pressure);
		}
	}

	public void measurementsChanged(){
		notifyObservers();
	}

	public void setMeasurements(float t,float h,float p){
		this.temperature = t;
		this.humidity = h;
		this.pressure = pressure;
		measurementsChanged();
	}
	//other get-method
}


public class CurrentConditionsDisplay implements Observer
{
	private float temperature;
	private float humidity;
	private float pressure;
	private Subject weatherData;

	public CurrentConditionsDisplay(Subject weatherData){
		this.weatherData = weatherData;
		weatherData.registerObserver(this);
	}

	public void update(float f,float h,float p){
		this.temperature = t;
		this.humidity = h;
		this.pressure = pressure;
		display();
	}

	public void display(){
		//do something
	}

}

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

		CurrentConditionsDisplay currentDisplay
			= new CurrentConditionsDisplay(weatherStation);

		weartherStation.setMeasurements(80,65,30.4f);
	}
}

 这样我们给subject新建一个observer的时候就不用修改subject的代码,实现松耦合

 

 

java内置的观察者模式
Observer interface
Observable class

 

1.新建一个observer
实现java.util.Observer接口,可以调用addObserver()和deleteoberser()

 

2.observable发送通知
 1>先调用setChanged()方法指明状态已经修改
 2>调用notifyObservers()方法:notifyObservers()或者notifyObservers(Object arg)
我们可以在setChanged()方法中加入一些特殊条件的判断

 

3.observer接收通知
 update(Observable o,Object arg)
 这里的object对应notifyObservers(Object obj)中的对象, 如果调用的notifyObservers()方法,则update中的Object为null

 observer可以用传递过来的参数也可以从Observable中通过getter方法得到 需要的参数

package pattern;

import java.util.Observable;

public class WeatherData extends Observable{

	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData(){
		
	}
	
	public void measurementsChanged(){
		setChanged();
		notifyObservers();
	}
	
	public void setMeasurements(float temperature,
			float humidity,
			float pressure){
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}

	public float getTemperature() {
		return temperature;
	}

	public float getHumidity() {
		return humidity;
	}

	public float getPressure() {
		return pressure;
	}
	
	
}

 

package pattern;

import java.util.Observable;
import java.util.Observer;

public class CurrentConditionsDisplay implements Observer {

	Observable observable;
	private float temperature;
	private float humidity;

	public CurrentConditionsDisplay(Observable observable) {
		this.observable = observable;
		observable.addObserver(this);
	}

	public void update(Observable obs, Object arg) {
		if (obs instanceof WeatherData) {
			WeatherData weatherData = (WeatherData) obs;
			this.temperature = weatherData.getTemperature();
			this.humidity = weatherData.getHumidity();
			display();
		}

	}

	public void display() {
		System.out.println("current condition: " + temperature + "F degrees and " + humidity + "% humidity");
	}

}

  

你可能感兴趣的:(设计模式,F#)