本篇首发于牧码人博客转载请加上此标示。
序言
设计模式的学习已经过半,这一次我想要讲的是观察者模式,也叫发布订阅模式。这个模式被应用的是比较多的,属于很重要的一种模式。jdk中已经给出了相应接口。java.util.Observable(被观察者)java.util.Observer(观察者)
讲这个之前,大家一定带着很多疑问,这个模式是啥?这个模式可以应用在哪?有多少已经在应用的场景?这个模式的好处是什么? 本文将会解决您的这些问题。
观察者模式的定义
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象监听某一主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象。使他们自动更新自己。
观察者模式的应用场景
- 消息队列
- 公众号
- java中的监听器
- 未完待续
观察者模式代码实现
看完类图相信大家对这个模式已经有点熟悉了。接下来看下代码实现加深下理解。 抽象主题(被观察者)
**
* @auther: Jan 橙寂
* @Date: 2019-8-15 11:12
* @Description:
* @Version: 1.0
*/
public interface Subject {
/**
* 添加观察者
* @param observer
*/
void attach(Observer observer);
/**
* 移除观察者
* @param observer
*/
void detach(Observer observer);
/**
* 通知
*/
void notifyObServer();
}
抽象观察者
/**
* @CLASSNAME Observer 观察者
* @Description
* @Auther Jan 橙寂
* @DATE 2019/8/15 0015 21:05
*/
public interface Observer {
void update();
}
具体的被观察者
/**
* @CLASSNAME ConcreteSubject
* @Description
* @Auther Jan 橙寂
* @DATE 2019/8/15 0015 21:27
*/
public class ConcreteSubject implements Subject {
List<Observer> observerList = new LinkedList<Observer>();
@Override
public void attach(Observer observer) {
observerList.add(observer);
}
@Override
public void detach(Observer observer) {
observerList.remove(observer);
}
@Override
public void notifyObServer() {
for (Observer temp : observerList) {
temp.update();
}
}
}
具体的观察者
/**
* @CLASSNAME ConcreteObserver 观察者
* @Description
* @Auther Jan 橙寂
* @DATE 2019/8/15 0015 22:02
*/
public class ConcreteObserver implements Observer
{
private String name;
public ConcreteObserver() {
}
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update() {
System.out.println("老板来了"+name+"赶紧收起手机来");
}
}
测试
/**
* @CLASSNAME Test
* @Description
* @Auther Jan 橙寂
* @DATE 2019/8/15 0015 22:03
*/
public class Test {
public static void main(String[] args) {
ConcreteObserver MrLiu=new ConcreteObserver("小刘");
ConcreteObserver MrHe=new ConcreteObserver("小何");
ConcreteSubject boss=new ConcreteSubject();
boss.attach(MrLiu);
boss.attach(MrHe);
boss.notifyObServer();
}
}
测试结果 老板来了小刘赶紧收起手机来 老板来了小何赶紧收起手机来
这个demo实现的是一个简单的场景,员工作为观察者,他们要玩手机所以他们就得时刻注意老板的变化。如果老板来了他们就得吧手机收起来。所以老板就是被观察者。
注意一个细节为什么用抽象? 在具体场景中观察者跟被观察者肯定不只一类。就像demo中的场景。被观察者不仅仅是老板,可能老板秘书也会来检查,董事长等等。用抽象是方便扩展正好符合依赖倒置原则。
总结
个人理解:观察者模式的本质就是,存在两个对象一个是主题(被观察者)。一个是观察者。这里说被观察者可能比较好理解。当被观察者发生了变化的情况下,那么观察者更新自己。比如小偷发现了警察然后就赶紧跑。员工发现老板来了,就放下手机努力工作。在这几个例子中小偷,员工就是观察者,老板跟警察就是被观察者。
就发布订阅而言,我觉得这两个词去形容这个模式是最佳的,也是比较好理解的一种。很简单公众号大家都关注过吧。关注后是不是经常能收到一些推送。这就是应用发布订阅模型。你关注(订阅)了我,我推送(发布)信息给你。
不管叫什么名字发布订阅也好,观察者也好。这个模式的核心就是当一个对象改变时,同时要去改变多个对象。
优点:解耦合,让所有对象依赖于抽象而不是具体。
注意:本文归作者所有,未经作者允许,不得转载