观察者设计模式
一、观察者设计模式
1、介绍
观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象Subject,依赖的对象为Observer,Subject通知Observer变化。
观察者模式类图:
角色:
Subject:表示观察对象,该角色定义了注册观察者和删除观察者的方法。它还声明了”获取现在的状态“的方法。
ConcreteSubject:表示具体的观察者对象。当自身状态发生变化,它会通知所有已经注册的Observer角色
Observer:表示观察者对象,负责接收来自Subject角色状态变化的通知。
ConcreteObserver:表示具体的观察者对象
二、普通方法
1、介绍
该案例讲述的是:当WeatherData天气数据变化,则通知CurrentConditions
该方案违反了ocp原则。当我有其它CurrentConditions想要获取WeatherData天气数据变化时,需要修改WeatherData
2、代码
/**
* @Author: dashu
* @Description: 当前天气情况
* @Date: 21:00
* @Version: 1.0
*/
public class CurrentConditions {
/**
* 气温
*/
private float temperature;
/**
* 气压
*/
private float pressure;
/**
* 湿度
*/
private float humidity;
/**
* 天气数据更新
*/
public void update(float temperature,float pressure,float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
/**
* 天气数据显示
*/
public void display(){
System.out.println("---今天气温:"+temperature+"---");
System.out.println("---今天气压:"+pressure+"---");
System.out.println("---今天湿度:"+humidity+"---");
}
}
/**
*
*
*
* @Author: dashu
* @Description: 天气数据
* @Date: 21:08
* @Version: 1.0
*/
public class WeatherData {
/**
* 气温
*/
private float temperature;
/**
* 气压
*/
private float pressure;
/**
* 湿度
*/
private float humidity;
/**
* 天气情况
*/
private CurrentConditions currentConditions;
public WeatherData(CurrentConditions currentConditions) {
this.currentConditions = currentConditions;
}
/**
* 获取气温
*/
public float getTemperature() {
return temperature;
}
/**
* 获取气压
*/
public float getPressure() {
return pressure;
}
/**
* 获取湿度
*/
public float getHumidity() {
return humidity;
}
/**
* 天气数据变化
*/
public void dataChange(){
currentConditions.update(getTemperature(),getPressure(),getHumidity());
}
/**
* 天气数据赋值
* @param temperature
* @param pressure
* @param humidity
*/
public void setData(float temperature,float pressure,float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
}
/**
* @Author: dashu
* @Description: 客户端
* @Date: 20:58
* @Version: 1.0
*/
public class Client {
public static void main(String[] args) {
CurrentConditions currentConditions = new CurrentConditions();
WeatherData weatherData = new WeatherData(currentConditions);
System.out.println("----当前天气情况----");
weatherData.setData(30,150,40);
System.out.println("----天气情况变化----");
weatherData.setData(40,160,20);
}
}
三、观察者设计模式编程
1、介绍
使用观察者模式编程。我们用集合的方式来管理Observer,这样我们无论是添加Observer还是删除Observer,都不用修改WeatherData
2、UML
3、代码
/**
* @Author: dashu
* @Description: 观察者接口
* @Date: 21:27
* @Version: 1.0
*/
public interface Observer {
/**
* 天气数据更新
*
* @param temperature 气温
* @param pressure 压力
* @param humidity 湿度
*/
public void update(float temperature,float pressure,float humidity);
}
/**
* @Author: dashu
* @Description: 百度网站
* @Date: 21:28
* @Version: 1.0
*/
public class BaiduSite implements Observer{
/**
* 气温
*/
private float temperature;
/**
* 气压
*/
private float pressure;
/**
* 湿度
*/
private float humidity;
/**
* 百度天气数据更新
*
* @param temperature 气温
* @param pressure 压力
* @param humidity 湿度
*/
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
/**
* 百度天气数据显示
*/
public void display(){
System.out.println("++++++++++++++++++++++++++++++++++++");
System.out.println("---百度网站 气温:"+temperature+"---");
System.out.println("---百度网站 气压:"+pressure+"---");
System.out.println("---百度网站 湿度:"+humidity+"---");
}
}
/**
* @Author: dashu
* @Description: 新浪网站
* @Date: 21:32
* @Version: 1.0
*/
public class SinaSite implements Observer{
/**
* 气温
*/
private float temperature;
/**
* 气压
*/
private float pressure;
/**
* 湿度
*/
private float humidity;
/**
* 新浪天气数据更新
*
* @param temperature 气温
* @param pressure 压力
* @param humidity 湿度
*/
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
/**
* 新浪天气数据显示
*/
public void display(){
System.out.println("++++++++++++++++++++++++++++++++++++");
System.out.println("---新浪网站 气温:"+temperature+"---");
System.out.println("---新浪网站 气压:"+pressure+"---");
System.out.println("---新浪网站 湿度:"+humidity+"---");
}
}
/**
* @Author: dashu
* @Description: 主题
* @Date: 21:34
* @Version: 1.0
*/
public interface Subject {
/**
* 注册一个观察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 移除一个观察者
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知观察者
*/
public void notifyObserver();
}
import java.util.ArrayList;
import java.util.List;
/**
* @Author: dashu
* @Description: 天气数据
* @Date: 21:36
* @Version: 1.0
*/
public class WeatherData implements Subject {
/**
* 气温
*/
private float temperature;
/**
* 气压
*/
private float pressure;
/**
* 湿度
*/
private float humidity;
/**
* 观察者集合
*/
private List<Observer> observers;
/**
* 构造方法
*/
public WeatherData() {
observers = new ArrayList<>();
}
/**
* 获取气温
*/
public float getTemperature() {
return temperature;
}
/**
* 获取气压
*/
public float getPressure() {
return pressure;
}
/**
* 获取湿度
*/
public float getHumidity() {
return humidity;
}
/**
* 天气数据变化
*/
public void dataChange() {
notifyObserver();
}
/**
* 天气数据赋值
*
* @param temperature
* @param pressure
* @param humidity
*/
public void setData(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
/**
* 注册一个观察者
*
* @param observer
*/
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
/**
* 移除一个观察者
*
* @param observer
*/
@Override
public void removeObserver(Observer observer) {
if (observers.contains(observer)) {
observers.remove(observer);
}
}
/**
* 通知观察者
*/
@Override
public void notifyObserver() {
for (Observer observer : observers) {
observer.update(temperature, pressure, humidity);
}
}
}
/**
* @Author: dashu
* @Description: 客户端
* @Date: 20:58
* @Version: 1.0
*/
public class Client {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
BaiduSite baiduSite = new BaiduSite();
SinaSite xinlangSite = new SinaSite();
weatherData.registerObserver(baiduSite);
weatherData.registerObserver(xinlangSite);
System.out.println("通知:");
weatherData.setData(10,20,30);
weatherData.removeObserver(xinlangSite);
weatherData.setData(1,1,1);
}
}