设计模式(五)观察者模式
746字约2分钟
设计模式
2019-06-11
观察者模式(Observer)是 JDK 中使用最多的模式之一
有时候,我们的对象需要在收到某些通知时及时作出响应,此时可以用观察者模式。观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
可以以订阅报纸类比,出版社作为发布者,所有订阅了报纸的用户,在有新报纸出版时,都会收到一份最新的报纸。只不过,在观察者模式中,出版社叫做 主题(Subject),订阅者叫 观察者(Observer)。
主题(Subject)
主题就是发送通知的人。
public interface Subject {
void registerObserver(Observer observer); // 注册一个观察者
void removeObserver(Observer observer); // 取消注册
void notifyObservers(); // 发送通知
}
一个可以发布小说和新闻的报社,它维护了一个观察者列表,需要订阅这家报社的人,都会被加到这个 List 进来。
public class Publisher implements Subject {
private List<Observer> observers;
private String story; // 小说
private String news; // 新闻
Publisher(){
observers = new ArrayList<>(6);
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
// 对每一个观察者都进行通知
@Override
public void notifyObservers() {
observers.forEach(o -> o.update(story, news));
}
// 设置通知信息
public void setMessages(String story, String news){
this.story = story;
this.news = news;
notifyObservers();
}
}
观察者(Observer)
观察者就是接收通知的人,当有通知来到,它自动会更新。
public interface Observer {
void update(String news); // 通知内容作为参数传递进来
}
假设有个新闻爱好者,想订阅新闻:
public class NewsObserver implements Observer {
private String news;
// update 是在报社那里被调用的
@Override
public void update(String story, String news) {
this.news = news;
displayNews();
}
public void displayNews(){
System.out.println(this.getClass().getName() + "获取到:" + this.news);
}
}
同理,小说爱好者,想订阅小说:
public class StoryObserver implements Observer {
private String story;
@Override
public void update(String story, String news) {
this.story = story;
displayStory();
}
public void displayStory(){
System.out.println(this.getClass().getName() + "获取到:" + this.story);
}
}
测试
public static void main(String[] args) {
// 初始化主题
Publisher dailyPublisher = new Publisher();
// 初始化观察者
Observer storyObserver = new storyObserver();
Observer newsObserver = new NewsObserver();
// 注册观察者
dailyPublisher.registerObserver(storyObserver);
dailyPublisher.registerObserver(newsObserver);
// 发布消息,观察者自动会收到
dailyPublisher.setMessages("最新小说", "每日新闻");
}
结果:
StoryObserver获取到:最新小说
NewsObserver获取到:每日新闻
Java 内置的观察者模式
在 java.util 包内,自带了 Observer接口
与 Observable类
,跟我们自己实现的观察者模式大同小异。但是,jdk内置的主题是继承Observable类
,而不是实现接口。但是在 java 9 中, 已经被标记为 deprecated
,原因是,他们的扩展性不够好,可以用 Listeners
代替。见 Observer is deprecated in Java 9. What should we use instead of it?
- 参考:《Head First 设计模式》