观察者模式

Posted 王晓东

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式相关的知识,希望对你有一定的参考价值。

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

 

发布者(发布数据)——观察者1(接收数据)

发布者(发布数据)——观察者2(接收数据)

 

 

 

在这里举例:

发布者:比喻为 气象局,

观察者:墨迹天气(观察者1)、雅虎天气(观察者2)

 

气象局用仪器设备能采集到天气的 温度、湿度、气压

而墨迹天气、雅虎天气需要交钱成为会员,在气象局注册,气象局才会给他们俩推送数据

气象局采集的温度、湿度、气压一改变,就得通知墨迹天气、雅虎天气

如果墨迹天气不给气象局交钱,气象局就得把墨迹天气删掉,不再给他推送数据

(理解就好,不要在意语病)

 

代码来了:

1、发布者(气象局)推送天气数据需要实现的功能——接口

(1)能让各种天气软件注册为会员

(2)不交钱,就删除他们

(3)气象局实时采集到新的数据,就推送给会员们

package Observer;

public interface Subject {

	//注册观察者
	public void registerObserver(Observer o);
	
	//删除观察者
	public void removeObserver(Observer o);
	
	//当主题状态改变时,此方法被调用,来通知所有的观察者
	public void notifyObservers();
	
}

  

2、观察者得到的更新的数据——接口

package Observer;
/*
 * 所有观察者都必须实现update()方法,以实现观察者接口
 * 
 */
public interface Observer {

	//当气象观测值改变时,主题会把这些状态值当作方法的参数,传给观察者
	public void update(float temperature , float humidity, float pressure);
	
}

  

3、墨迹天气(观察者1)和雅虎天气(观察者2)都要显示从气象局得到的数据,这里单独提个接口,就是要让观察者必须实现display()方法,省的到时候忘了实现

package Observer;

public interface DisplayElement {

	//当布告板需要显示时,调用此方法
	public void display();
}

  

4、发布者(气象局)推送天气数据的功能实现类

package Observer;

import java.util.ArrayList;

public class WeatherData implements Subject{

	private ArrayList observers;	//观察者集合
	
	private float temperature;	//温度
	private float humidity;		//湿度
	private float pressure;		//气压
	
	public WeatherData(){
		observers = new ArrayList();
	}
	
	@Override
	public void registerObserver(Observer o) {
		observers.add(o);
	}

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

	@Override
	public void notifyObservers() {
		for (int i = 0; i<observers.size(); i++) {
			Observer observer = (Observer) observers.get(i);
			observer.update(temperature, humidity, pressure);
		}
	}
	
	//数据改变,通知所有观察者
	public void setMeasurements(float temperature, float humidity, float pressure){
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}

	public void measurementsChanged(){
		notifyObservers();
	}
}

  

5、观察者(墨迹天气、雅虎天气等)接收数据并显示的功能实现类

package Observer;
/*
 * 观察者1:
 * 实现了Observer接口,可以从WeatherData对象中获得改变
 * 实现了DisplayElement接口,因为布告板都要展示数据,必须实现,防止忘记实现
 */
public class CurrentConditionsDisplay  implements Observer, DisplayElement{

	private float temperature;	//温度
	private float humidity;		//湿度
	private float pressure;		//气压
	private Subject weatherData;
	
	
	public CurrentConditionsDisplay(Subject weatherData){
		this.weatherData = weatherData;
		weatherData.registerObserver(this);	//注册当前观察者(this),Weather的ArrayList就添加了此观察者
	}
	
	@Override
	public void display() {
		System.out.println("温度:" + temperature + "\n" + "湿度:" + humidity + "\n" + "气压:" + pressure);
	}

	@Override
	public void update(float temperature, float humidity, float pressure) {
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		display();	//值改变的时候就display()显示数据
	}

}

  

可以建立更多的观察者,display()不同的内容

 

6、Main方法:测试类

package Observer;

public class Main {

	public static void main(String[] args) {
		
		//建立WeatherData对象
		WeatherData weatherData = new WeatherData();
		
		//建立一个观察者(布告板),用来显示从主题获得的数据
		CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
		
		//可以建立更多的观察者,display()不同的内容
		
		weatherData.setMeasurements(50, 40, 30);
		//数据实时改变,就会输出最新的数据
		weatherData.setMeasurements(88, 77, 66);
	}

}

  

 

以上是关于观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

未调用 LiveData 观察者

Java设计模式补充:回调模式事件监听器模式观察者模式(转)

如何为片段设置观察者

永远观察实时数据的片段

设计模式观察者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

观察者模式