观察者模式--Observer

本文通过气象监测应用解释观察者模式的概念,包括主题、观察者和布告板之间的关系,以及如何实现主题和观察者之间的耦合,使得观察者能够自动接收主题状态的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义:定义了对象之间的一对多依赖, 这样一来, 当一个对象改变状态时, 它的所有依赖者都会收到通知并且自动更新;

举个例子:想知道咱们公司最新MM情报吗?加入公司的MM情报邮件组就行了,tom负责搜集情报,他发现的新情报不用一个一个通知我们,直接发布给邮件组,我们作为订阅者(观察者)就可以及时收到情报啦。

在本文中, 我们采用气象监测应用来阐述。主要包括三个部分:气象站(获取实际气象数据的物理装置)、WeatherData对象(追踪来自气象站的数据, 并更新布告板),布告板(显示目前天气状况给用户看)。布告板有多个, 可能显示气象的不同信息。 在这里气象是主题, 布告板也就是观察者。 本例给出两个布告板。

主题和观察者定义了一对多的关系, 观察者依赖于此主题, 只要主题状态一有变化, 观察者就会被通知。每个主题可以有多个观察者。 

1、主题subject定义:

subject.java

public interface DisplayElement {
	public void display();
}
WeatherData.java

public class WeatherData implements Subject{
	private ArrayList<Observer> observers;
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData() {
		observers = new ArrayList<Observer>();
	}
	
	@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(i);
	}

	@Override
	public void notifyObserver() {
		for (int i  = 0; i < observers.size(); i++) {
			Observer ob = observers.get(i);
			ob.update(temperature, humidity, pressure);
		}
	}
	
	public void measurementsChanged() {
		notifyObserver();
		System.out.println("======================");
	}
	
	public void setMeasurements(float temp, float humidity, float pressure) {
		this.temperature = temp;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}
	
}

2、观察者相关定义:

Observer.java

public interface Observer{
	public void update(float temp, float humidity, float pressure);
}
DisplayElement.java
public interface DisplayElement {
	public void display();
}
布告板1:CurrentConditionsDisplay.java

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);
	}
	
	@Override
	public void display() {
		System.out.println("[CurrentConditions]current conditions:" + temperature + 
				"F degrees and" + humidity + "% humidity and " + pressure + "pressure");	
	}

	@Override
	public void update(float temp, float humidity, float pressure) {
		this.temperature = temp;
		this.humidity = humidity;
		this.pressure = pressure;
		display();
	}
	
}
布告板2:StatisticsDisplay.java

public class StatisticsDisplay implements Observer, DisplayElement {
	private float AverageTemp = 0;
	private float MaxTemp = 0;
	private float MinTemp = 0;
	
	public StatisticsDisplay(Subject weatherData) {
		weatherData.registerObserver(this);
	}
	
	@Override
	public void display() {
		System.out.println("[Statistics]Max temperature:" + MaxTemp + 
				" Min temperature:" + MinTemp + " Average temperature:" + AverageTemp);	
		
	}

	@Override
	public void update(float temp, float humidity, float pressure) {
		if (temp > MaxTemp ) MaxTemp = temp;
		else if (temp < MinTemp) MinTemp = temp;
		
		if (MaxTemp == 0 ) MaxTemp = temp;
		if (MinTemp == 0) MinTemp = temp;
		AverageTemp = (MaxTemp + MinTemp) / 2;
		display();
	}
	
}

3、实例程序

WeatherMain.java

public class WeatherMain {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
		StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
		
		weatherData.setMeasurements(80, 65, 30.4f);
		weatherData.setMeasurements(82, 70, 29.2f);
		weatherData.setMeasurements(78, 90, 29.2f);
	}											 
}


注: 代码参照《Head First设计模式》





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值