观察者模式: 定义一系列对象之间的一对多关系;当一个对象改变状态,它的依赖都会被通知。 主要由主题(Subject)和观察者(Observer)组成。
代码实现
java
package com.designpatterns.observer;
/**
* 定义主题接口
*/
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
java
/**
* 定义观察者接口
*/
public interface Observer {
public void update(float temp,float humidity,float pressure);//当主题状态变更时,被调用
}
java
package com.designpatterns.observer;
/**
* 定义天气情况显示的元素接口
*/
public interface DisplayElement {
public void display();
}
java
package com.designpatterns.observer;
import java.util.ArrayList;
import java.util.List;
/**
* 具体主题的实现
*/
public class WeatherDataConcretSubject implements Subject{
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherDataConcretSubject(){
observers=new ArrayList<>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature,humidity,pressure); //观察者更新天气数据
}
}
public void measurementsChanged(){
notifyObservers();//当测量到新的天气数据,通知观察者
}
/**
* 设置天气测试数据
* @param temperature
* @param humidity
* @param pressure
*/
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
measurementsChanged();
}
}
java
package com.designpatterns.observer;
/**
*
* 具体每个观察者实现。每个观察着注册具体主题以接口更新
*
*
* 显示当前的天气情况
*
*
*/
public class CurrentConditionsDisplay implements Observer, DisplayElement{
private float temperature;
private float humidity;
private WeatherDataConcretSubject weatherDataConcretSubject;
public CurrentConditionsDisplay(WeatherDataConcretSubject weatherDataConcretSubject){
this.weatherDataConcretSubject=weatherDataConcretSubject;
weatherDataConcretSubject.registerObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature=temp;
this.humidity=humidity;
display();
}
@Override
public void display() {
System.out.println("Current conditions:"+temperature+"F degrees and "+ humidity+"% humidity ");
}
}
java
package com.designpatterns.observer;
public class ForecastDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private WeatherDataConcretSubject weatherDataConcretSubject;
public ForecastDisplay(WeatherDataConcretSubject weatherDataConcretSubject){
this.weatherDataConcretSubject=weatherDataConcretSubject;
weatherDataConcretSubject.registerObserver(this);
}
@Override
public void display() {
//显示预报的天气
System.out.println("ForecastDisplay:"+temperature+"F degrees and "+ humidity+"% humidity ");
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature=temp;
this.humidity=humidity;
display();
}
}
java
package com.designpatterns.observer;
public class StatisticsDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private WeatherDataConcretSubject weatherDataConcretSubject;
public StatisticsDisplay(WeatherDataConcretSubject weatherDataConcretSubject){
this.weatherDataConcretSubject=weatherDataConcretSubject;
weatherDataConcretSubject.registerObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature=temp;
this.humidity=humidity;
display();
}
@Override
public void display() {
//显示测量的avg,min,max值
System.out.println("StatisticsDisplay:"+temperature+"F degrees and "+ humidity+"% humidity ");
}
}
java
package com.designpatterns.observer;
/**
* 观察者模式测试
*/
public class WeatherStationTest {
public static void main(String[] args) {
WeatherDataConcretSubject weatherDataConcretSubject=new WeatherDataConcretSubject();
CurrentConditionsDisplay currentConditionsDisplay=new CurrentConditionsDisplay(weatherDataConcretSubject);
StatisticsDisplay statisticsDisplay=new StatisticsDisplay(weatherDataConcretSubject);
ForecastDisplay forecastDisplay=new ForecastDisplay(weatherDataConcretSubject);
//设置模拟的气象数据
weatherDataConcretSubject.setMeasurements(80,65,30.4f);
weatherDataConcretSubject.setMeasurements(82,70,29.2f);
weatherDataConcretSubject.setMeasurements(78,90,29.2f);
}
}