Java设计模式:观察者模式学习与分析

1 前言

  1. 设计模式让你和其他开发人员之间有共享的词汇,一旦懂得这些词汇,和其他开发人员沟通就很容易。
  2. 设计模式也可以把你的思考架构的层次提高到模式层面,而不是仅停留在琐碎的对象上。

2 观察者模式

Java设计模式:观察者模式学习与分析_第1张图片
3. 观察者模式定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知,并自动更新。
4. 封装变化
5. 多用组合,少用继承
6. 针对接口编程,不针对实现编程
7. 为交互对象之间的松耦合设计而努力

3 实现

Java设计模式:观察者模式学习与分析_第2张图片

  1. 主题用一个共同接口来更新观察者;
  2. 松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现的接口。
  3. 若针对实现编程,会导致我们以后在增加或删除布告板时必须修改大量代码。
  4. 改变的地方,需要封装起来。

4 代码(Java)

4.1 定义Observer接口

public interface Observer {
	//所有的观察者都必须实现update()方法,以实现观察者接口。
	//当气象观测值改变时,主题会把这些状态值当作方法的参数,传送给观察者
	public void update(float temp, float humidity, float pressure);
}

4.2 定义DisplayElement接口

public interface DisplayElement {
	//DisplayElement接口只包含了一个方法,也就是display()。当布告板需要显示时,调用此方法。
	public void display();
}

4.3 定义Subject接口

package Subject;

public interface Subject {
	
	//下面的两个方法都需要一个观察者作为变量,该观察者是用来注册或被删除的
	public void registerObserver(Observer o);
	public void removeObserver(Observer o);
	//当主题改变时,这个方法会被调用,以通知所有的观察者
	public void notifyObservers();
}

4.4 实现Subject接口,创建WeatherData类

import java.util.ArrayList;

//WeatherData实现了Subject接口
public class WeatherData implements Subject {
	//ArrayList记录观察者,ArrayList在构造器中建立
	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) {
		// TODO Auto-generated method stub
		//当观察者来注册时,只需要把它加到ArrayList里面
		observers.add(o);
		System.out.println(observers.size());
	}

	@Override
	public void removeObserver(Observer o) {
		// TODO Auto-generated method stub
		int i = observers.indexOf(o);
		if(i >= 0) {
			//当观察者取消注册时,只需要把它从ArrayList删除里面
			observers.remove(i);
		}
	}

	@Override
	public void notifyObservers() {
		// TODO Auto-generated method stub
		//把状态告诉每个观察者
		for(int i = 0; i < observers.size(); i++) {
			Observer observer = (Observer)observers.get(i);
			observer.update(temperature, humidity, pressure);
		}
	}
	
	public void measurementsChanged() {
		notifyObservers();
	}
	
	//主题更改状态的API
	public void setMeasurements(float temperature, float humidity, float pressure) {
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}
	
	//WeatherData的其他方法
}

4.5 实现Observer, DisplayElement接口,创建CurrentConditionsDisplay 类

//CurrentConditionsDisplay 实现了 Observer 接口,所以可以从 WeatherData 对象中获得改变
public class CurrentConditionsDisplay implements Observer, DisplayElement{
	private float temperature;
	private float humidity;
	private Subject weatherData_this;
	
	//构造器需要weatherData对象(主题),作为注册使用
	public CurrentConditionsDisplay(Subject weatherData) {
		this.weatherData_this = weatherData;
		weatherData_this.registerObserver(this);
	}
	
	@Override
	public void update(float temperature, float humidity, float pressure) {
		// TODO Auto-generated method stub
		this.temperature = temperature;
		this.humidity = humidity;
		display();
	}
	
	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("Current conditions:\n"+"temperature:"+temperature+"\nhumidity"+humidity);
	}
}

4.6 实现Observer, DisplayElement接口,创建ForecastDisplay 类


public class ForecastDisplay implements Observer, DisplayElement{
	
	private float temperature;
	private float humidity;
	private float pressure;
	private Subject weatherData_this;
	
	public ForecastDisplay(Subject weatherData) {
		this.weatherData_this = weatherData;
		weatherData_this.registerObserver(this);
	}
	
	@Override
	public void update(float temperature, float humidity, float pressure) {
		// TODO Auto-generated method stub
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		display();
	}
	
	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("Forecast conditions:\n"+"temperature:"+temperature+"\nhumidity:"+humidity + "\npressure:" + pressure);
	}
}

4.7 用例测试

public class WeatherStation {
	public static void main(String[] args) {
		//首先,建立一个WeatherData对象
		WeatherData weatherData = new WeatherData();
		
		CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
		ForecastDisplay          forecastDisplay = new ForecastDisplay(weatherData);
		//模拟观测值的更新
		weatherData.setMeasurements(82, 70, 29.2f);
		
		CurrentConditionsDisplay currentDisplay2  = new CurrentConditionsDisplay(weatherData);
		ForecastDisplay          forecastDisplay2  = new ForecastDisplay(weatherData);
		//模拟观测值的更新
		weatherData.setMeasurements(80, 65, 30.4f);

	}
}

输出:

1
2
Current conditions:
temperature:82.0
humidity70.0
Forecast conditions:
temperature:82.0
humidity:70.0
pressure:29.2
3
4
Current conditions:
temperature:80.0
humidity65.0
Forecast conditions:
temperature:80.0
humidity:65.0
pressure:30.4
Current conditions:
temperature:80.0
humidity65.0
Forecast conditions:
temperature:80.0
humidity:65.0
pressure:30.4

代码下载
提取码:338i

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