对象之间存在一对一或者一对多依赖,当一个对象改变状态,依赖它的对象会受到通知并自动更新。例如:MQ(消息队列Message Queue)就是一种观察者模式,发布者发布消息,所有订阅者都能获取到信息。
优点
1.观察者和被观察者式抽象耦合的。
2.建立了一套触发机制。
缺点
1.如果一个被观察者对象有很多直接/间接的观察者,所有的观察者都通知会花费很多时间。
2.如果在观察者和观察目标存在循环依赖,观察目标会触发循环调用,严重可导致系统崩溃。
小编每天上班午休之后,下午工作铃声想起之前都会回想一下今天上午做了什么事情,方便计划下午需要工作那一块内容,上午一般由3部分组成:
1.上班时间到,开始工作
2.午饭时间到,开始吃午饭
3.午休时间到,开始午休
每次下午睡醒觉都会想到这三个方面,我们将该案例应用到观察者模式,早上工作、吃午饭和睡午觉都是由下午工作铃想起后触发回想事件,下面用代码实现:
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 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(); } }
总结
观察者模式一旦观察者发生改变,会通知相关的被观察对象进行改变,类似微信订阅公众号,公众号推送新的推文给所有订阅者。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)