目录
观察者模式
在观察者模式中有两类角色,即观察者和被观察者,被观察者如果有变化会主动通知观察者,这是核心思想。
那么是如何做到这点的呢 ?就是通过被观察者维护一个观察者列表。
代码如:
观察者接口
package net.sytm;
/**
* Created by aoc on 2016/11/11.
*/
public interface Observer {
void notifi(String s);
}
所有实现这个接口的都是观察者。
观察者
package net.sytm;
/**
* Created by aoc on 2016/11/11.
*/
public class A implements Observer {
public String name;
public A(String name) {
this.name = name;
}
@Override
public void notifi(String s) {
System.out.println(name + s);
}
}
现在类A就是一个观察者了
被观察者
package net.sytm;
import java.util.ArrayList;
import java.util.List;
/**
* Created by aoc on 2016/11/11.
*/
public class B {
private List<Observer> list;
public B() {
list = new ArrayList<>();
}
public void register(Observer observer) {
list.add(observer);
}
public void send(String s) {
for (Observer observer : list) {
observer.notifi(s);
}
}
}
首先定义一个观察者集合List,然后通过调用register()方法把观察者添加集合里。这样就得到了所有的观察者。
package net.sytm;
public class Main {
public static void main(String[] args) {
Observer observer1= new A("我是观察者1");
Observer observer2 = new A("我是观察者2");
B b = new B();
b.register(observer1);
b.register(observer2);
b.send("---->我是被观察者我要发消息了");
}
}
当调用send方法的时候,被观察者就会通知所有的观察者,我被调用了。
我是观察者1---->我是被观察者我要发消息了
我是观察者2---->我是被观察者我要发消息了
发布订阅模式
大概很多人都和我一样,觉得发布订阅模式里的Publisher,就是观察者模式里的Subject,而Subscriber,就是Observer。Publisher变化时,就主动去通知Subscriber。
其实并不是。
在发布订阅模式里,发布者,并不会直接通知订阅者,换句话说,发布者和订阅者,彼此互不相识。
互不相识?那他们之间如何交流?
答案是,通过第三者,也就是在消息队列里面,我们常说的经纪人Broker。
- 发布者只需告诉Broker,我要发的消息,topic是AAA;
- 订阅者只需告诉Broker,我要订阅topic是AAA的消息;
于是,当Broker收到发布者发过来消息,并且topic是AAA时,就会把消息推送给订阅了topic是AAA的订阅者。当然也有可能是订阅者自己过来拉取,看具体实现。
也就是说,发布订阅模式里,发布者和订阅者,不是松耦合,而是完全解耦的。
放一张极简的图,给大家对比一下这两个模式的区别:
总结
从表面上看:
- 观察者模式里,只有两个角色 —— 观察者 + 被观察者
- 而发布订阅模式里,却不仅仅只有发布者和订阅者两个角色,还有一个经常被我们忽略的 —— 经纪人Broker
往更深层次讲:
- 观察者和被观察者,是松耦合的关系
- 发布者和订阅者,则完全不存在耦合
从使用层面上讲:
- 观察者模式,多用于单个应用内部
- 发布订阅模式,则更多的是一种跨应用的模式(cross-application pattern),比如我们常用的消息中间件