设计模式——观察者模式
Posted 54chensongxia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——观察者模式相关的知识,希望对你有一定的参考价值。
概念
观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
观察者模式结构图
该模式包含四个角色:
- 抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
- 抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
- 具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
- 具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
代码示例
下面用一个微信公众号发布文章的列子来简单讲解下观察者模式。通过这个列子,能帮助我们加深对观察者模式的理解。
step1:定义Subject和Observer接口
//定义一个微信公众号接口,相当于类图中的Subject角色
public interface WeChatOfficialAccount {
public void registerObserver(WeChatObserver observer);
public void removeObserver(WeChatObserver observer);
public void notifyObserver(String message);
}
//定义一个微信用户接口,相当于类图中的Observer角色
public interface WeChatObserver {
void pullArticle(String message);
}
step2:编写实现类
//这步没什么好说的
public class MyWeChatOfficialAccount implements WeChatOfficialAccount {
private List<WeChatObserver> observerList;
public MyWeChatOfficialAccount(){
this.observerList = new ArrayList<>();
}
@Override
public void registerObserver(WeChatObserver observer) {
this.observerList.add(observer);
}
@Override
public void removeObserver(WeChatObserver observer) {
this.observerList.remove(observer);
}
@Override
public void notifyObserver(String message) {
observerList.forEach(item->item.pullArticle(message));
}
}
public class WeChatUser implements WeChatObserver {
private String userName;
public WeChatUser(String userName){
this.userName = userName;
}
@Override
public void pullArticle(String message) {
System.out.println(userName+" receive message:"+message);
}
}
step3:编写客户端类
public class Main {
public static void main(String[] args) {
WeChatUser user1 = new WeChatUser("csx-java");
WeChatUser user2 = new WeChatUser("zr-php");
WeChatOfficialAccount officialAccount = new MyWeChatOfficialAccount();
//csx和zr两个用户都订阅了这个公众号
officialAccount.registerObserver(user1);
officialAccount.registerObserver(user2);
//公众号发布文章,订阅者都会受到文章通知
officialAccount.notifyObserver("Java is good...");
//zr取消订阅
officialAccount.removeObserver(user2);
//再次发布文章
officialAccount.notifyObserver("Java is more popular than php");
}
}
优缺点
优点
- 观察者和被观察者是抽象耦合的(面向接口耦合)。
- 建立一套通知触发机制。
缺点
- 如果需要通知的观察者太多,可能会比较耗时。其中一个观察者通知出问题的话可能会影响其他观察者的通知。
和生产者消费者模式的区别
这两种模式比较相似。其实我个人觉得没有太大的必须去纠结两者的区别。如果非要说下两者的区别的话,大概有:
- 生产者模式中成产者一般不负责通知观察者,只是负责生产消息,然后将消息分发到一个消息队列。
- 生产者消费者模式一般用于系统和系统之间解耦,而观察者模式一般用于系统内的某些逻辑。(可以参考Spring的ApplicationListener,这是一种金典的观察者模式的使用。)
参考
- https://www.cnblogs.com/Leo_wl/p/5415616.html
- https://www.cnblogs.com/luohanguo/p/7825656.html
- 和生产者消费者模式的区别
以上是关于设计模式——观察者模式的主要内容,如果未能解决你的问题,请参考以下文章
Java设计模式补充:回调模式事件监听器模式观察者模式(转)