观察者模式提供了一种对象设计,让被观察者和观察者之间松耦合,降低对象之间的相互依赖。
前言
最近在看Head First 设计模式,了解下观察者模式。书本上实现比较麻烦点,写个简单的。
- 观察者持有主题的引用,耦合比较紧密。
- 对于观察者列表,没考虑并发
观察者模式简单实现
类图
代码实现
主题接口
主题实现
public class WeatherSubject implements Subject {
private Set<Observer> observers;
//天气状态
private String state;
public WeatherSubject() {
this.observers = new HashSet<>();
}
public void notice() {
System.out.println("获取到最新天气状态");
System.out.println("状态更新了,开始通知观察者。。。");
// 通知观察者
for (Observer observer : observers) {
observer.update("最新天气信息:" + state);
}
}
@Override
public void register(Observer observer) {
observers.add(observer);
}
@Override
public void delete(Observer observer) {
observers.remove(observer);
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
观察者
public interface Observer {
void update(String content);
}
观察者实现
public class ObserverBJ implements Observer {
@Override
public void update(String content) {
System.out.println("北京观察站收到更新消息:" + content);
}
}
public class ObserverSH implements Observer {
@Override
public void update(String content) {
System.out.println("上海观察站收到更新消息:"+content);
}
}
测试
public class ObServerTest {
public static void main(String[] args) {
Subject weather = new WeatherSubject();
System.out.println("上海站注册天气主题");
Observer sh=new ObserverSH();
weather.register(sh);
System.out.println("北京站注册天气主题");
Observer bj=new ObserverBJ();
weather.register(bj);
System.out.println("天气信息更新");
((WeatherSubject) weather).setState("温度29度,湿度30");
weather.notice();
}
}
JDK内置观察者模式
类图
实现
继承Observable
,直接实现
public class WeatherData extends Observable {
//天气状态
private String state;
@Override
protected synchronized void setChanged() {
super.setChanged();
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
System.out.println("接受到天气信息更新。。。:"+state);
super.setChanged();
System.out.println("天气信息更新了,通知观察者。。。");
super.notifyObservers(state);
}
}
实现观察者
public class ObserverNJ implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("南京站 最新天气信息: " + arg);
}
}
public class ObserverHZ implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("杭州站 最新天气信息:"+arg);
}
}
测试
public class JDKObserverTest {
public static void main(String[] args) {
Observable weatherData=new WeatherData();
ObserverHZ hz=new ObserverHZ();
ObserverNJ nj=new ObserverNJ();
weatherData.addObserver(hz);
weatherData.addObserver(nj);
((WeatherData) weatherData).setState("温度29度,湿度30\"");
//((WeatherData) weatherData).setChanged();
//weatherData.notifyObservers("温度29度,湿度30");
}
}
内置模式优点
- 封装常用操作
- 线程安全
内置模式缺点
JDK内置模式也是有些小问题的。
- JDK10以后不支持
-
Observable
要使用必须被继承,Java不支持多继承,限制了
Observable
的复用潜力,违反”多组合、少继承”的设计原则 -
方法保护
这意味着,要使用setChanged
方法,必须继承Observable
。
可以的话,自己实现观察者模式吧。不过需要解决观察者列表并发修改的问题。
适用场景
观察者模式适用场景
- 被观察者的对象有状态,且变更比较频繁
- 被观察者需要持有观察者列表。
- 能够通知观察者
- 具体的观察者实现统一接口
观察者模式,封装了变化,在对象之间定义一对多的依赖,当一个对象状态改变时,依赖他的对象都会收到通知,并自动更新。
作者:Wuxinshui
出处:http://wuxinshui.github.io
版权归作者所有,转载请注明出处