定义:
对象之间存在一对一或者一对多依赖,当一个对象改变状态,依赖它的对象会受到通知并自动更新。例如:MQ(消息队列Message Queue)就是一种观察者模式,发布者发布消息,所有订阅者都能获取到信息。
优点
1.观察者和被观察者式抽象耦合的。 2.建立了一套触发机制。
缺点
1.如果一个被观察者对象有很多直接/间接的观察者,所有的观察者都通知会花费很多时间。 2.如果在观察者和观察目标存在循环依赖,观察目标会触发循环调用,严重可导致系统崩溃。
二、使用案例
1.场景
小编每天上班午休之后,下午工作铃声想起之前都会回想一下今天上午做了什么事情,方便计划下午需要工作那一块内容,上午一般由3部分组成: 1.上班时间到,开始工作 2.午饭时间到,开始吃午饭 3.午休时间到,开始午休 每次下午睡醒觉都会想到这三个方面,我们将该案例应用到观察者模式,早上工作、吃午饭和睡午觉都是由下午工作铃想起后触发回想事件,下面用代码实现:
定义工作事件workInfo
public class WorkInfo{
public void message() {
System.out.println("开始工作");
}
}
定义吃午饭事件EatInfo
public class EatInfo{
public void message() {
System.out.println("到饭点,该吃饭了...");
}
}
定义午休事件SleepInfo
public class SleepInfo{
public void message(){
System.out.println("午休时间到,该睡觉了...");
}
}
根据观察者模式思想,这里我将【开始工作】、【吃午饭】和【睡午觉】作为需要被通知的对象(待回想的事件),由下午工作铃声想起触发,每次闹铃想起都会回想这三件事:
定义下午铃声类Clock和待回想的对象(需要通知的对象)
public abstract class AbstactInfo {
private Clock clock;
public abstract void message();
}
public class Clock {
private List<AbstactInfo> infoList = new ArrayList<>();
public void said(){
System.out.println("下午铃声响了,开始回想上午做到哪了...");
update();
}
private void update(){
for (AbstactInfo info : infoList){
info.message();
}
}
public void addInfo(AbstactInfo info){
infoList.add(info);
}
}
待通知事件都继承抽象类AbstactInfo
public class WorkInfo extends AbstactInfo{
@Override
public void message() {
System.out.println("开始工作");
}
}
public class EatInfo extends AbstactInfo{
@Override
public void message() {
System.out.println("到饭点,该吃饭了...");
}
}
public class SleepInfo extends AbstactInfo{
@Override
public void message(){
System.out.println("午休时间到,该睡觉了...");
}
}
2.运行结果
public class MainTest {
public static void main(String[] args) {
Clock clock = new Clock();
WorkInfo workInfo = new WorkInfo();
clock.addInfo(workInfo);
EatInfo eatInfo = new EatInfo();
clock.addInfo(eatInfo);
SleepInfo sleepInfo = new SleepInfo();
clock.addInfo(sleepInfo);
clock.said();
}
}
总结
观察者模式一旦观察者发生改变,会通知相关的被观察对象进行改变,类似微信订阅公众号,公众号推送新的推文给所有订阅者。
|