观察者模式
说明
观察者模式(Observer Pattern)属于行为型模式,又叫:发布-订阅模式(Publish-Subscribe)、模型-视图模式(Model-View)、源-监听器模式(Source-Listener)、从属(Dependents)模式。
定义一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听,使得每当主题对象发生变化时,所有依赖于它的对象都会得到通知并被自动更新。
结构
观察者模式主要角色如下:
抽象主题(Subject):定义主题对象的接口;
具体主题(ConcreteSubject):具体主题对象,也就是被观察者,当其发生改变时,会通知所有依赖的观察者;
抽象观察者(Observer):定义了响应通知的接口;
具体观察者(ConcreteObserver):实现响应通知的接口。
代码案例
使用Java现成JKD实现观察者模式
具体主题(ConcreteSubject)
/**
* 气象局对象(被观察对象)
* 具体主题(ConcreteSubject)
*/
public class WeatherBureau extends Observable {
public String getName() {
return name;
}
private String name = "深圳气象局";
private static final WeatherBureau weatherBureau = new WeatherBureau();
private WeatherBureau(){
}
public static WeatherBureau getInstance(){
return weatherBureau;
}
/**
* 发布天气预报
* @param weather
* @return
*/
public void publish(Weather weather){
System.out.println(this.name + "发布天气预报:");
System.out.println("\t天气:" + weather.getWeather());
System.out.println("\t气温:" + weather.getTemperature());
setChanged();
notifyObservers(weather);
}
}
具体观察者(ConcreteObserver)
/**
* 天气预报观察者
* 具体观察者(ConcreteObserver)
*/
public class WeatherObserver implements Observer {
private String name;
public WeatherObserver(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
// 被观察者对象
WeatherBureau wb = (WeatherBureau)o;
// 参数
Weather weather = (Weather) arg;
System.out.println("===========================================================");
System.out.println(this.name + "接收到" + wb.getName() + "发布的天气预报!!!");
System.out.println("\t天气预报内容:天气 -> " + weather.getWeather() + " 气温 -> " + weather.getTemperature());
}
}
DTO传输对象
/**
* 天气对象
*/
public class Weather {
// 天气
private String weather;
// 温度
private Double temperature;
public Weather(String weather, Double temperature) {
this.weather = weather;
this.temperature = temperature;
}
public String getWeather() {
return weather;
}
public void setWeather(String weather) {
this.weather = weather;
}
public Double getTemperature() {
return temperature;
}
public void setTemperature(Double temperature) {
this.temperature = temperature;
}
}
客户端
public class Test {
public static void main(String[] args) {
// 获得气象局对象
WeatherBureau weatherBureau = WeatherBureau.getInstance();
// 创建天气预报观察者
WeatherObserver wo1 = new WeatherObserver("张三");
WeatherObserver wo2 = new WeatherObserver("李四");
// 将观察者添加到观察者列表中
weatherBureau.addObserver(wo1);
weatherBureau.addObserver(wo2);
// 创建天气预报对象
Weather weather = new Weather("多云",27.1);
// 发布天气预报
weatherBureau.publish(weather);
}
}
输出结果
深圳气象局发布天气预报:
天气:多云
气温:27.1
===========================================================
李四接收到深圳气象局发布的天气预报!!!
天气预报内容:天气 -> 多云 气温 -> 27.1
===========================================================
张三接收到深圳气象局发布的天气预报!!!
天气预报内容:天气 -> 多云 气温 -> 27.1
使用guava实现观察者模式
引入guava依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
定义观察者对象,使用@Subscribe注解标注回调方法
/**
* 天气预报观察者
* 具体观察者(ConcreteObserver)
*/
public class WeatherObserver {
private String name;
public WeatherObserver(String name) {
this.name = name;
}
@Subscribe
public void observer(Weather weather) {
System.out.println("===========================================================");
System.out.println(this.name + "接收到发布的天气预报!!!");
System.out.println("\t天气预报内容:天气 -> " + weather.getWeather() + " 气温 -> " + weather.getTemperature());
}
}
客户端
public class Test {
public static void main(String[] args) {
// 创建事件总线
EventBus eventBus = new EventBus();
// 创建观察者对象
WeatherObserver w1 = new WeatherObserver("张三");
WeatherObserver w2 = new WeatherObserver("李四");
// 注册到消息总线
eventBus.register(w1);
eventBus.register(w2);
// 创建天气对象
Weather weather = new Weather("多云",27.1);
// 发布
eventBus.post(weather);
}
}