观察者模式流程图
推模型与拉模型
观察者模式的定义
观察者模式subject订阅发布
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
优点: 1,观察者模式实现了观察者和目标之间的抽象耦合; 2,观察者模式实现了动态联动 3,观察者模式支持广播通信 缺点: 可能会引起无谓的操作---->引起误更新
认识观察者模式:
1、目标与观察者之间的关系
一对一、一对多、多对一(观察者需要定义多个update方法用于区分)
2、单项依赖
观察者依赖目标,观察者一直在等待目标的通知
3、命名建议
观察者模式又被称为发布订阅模式
①目标接口的定义,名称加Subject后缀
②观察者接口的定义,名称加Observer后缀
③观察者接口的更新方法,名称为update
4、触发通知的时机
先修改状态再通知,否则会导致状态不一致
5、观察者模式的调用顺序示意图
①准备阶段
创建目标对象-》创建观察者对象-》向目标对象注册观察者对象
②运行阶段
改变目标对象的状态-》通知所有注册的观察者对象进行相应的处理-》回调目标对象,获取相应的数据
6、通知的顺序
多个观察者之间是没有先后顺序的
观察者模式流程图
观察者 代码
extennds Observabl
this.setChanged();
this.notifyObservers();
观察者模式的本质
拉模型。。
观察者模式定义
重点在于通知方法的实现,通常的通知方式为广播方式,但要根据不同的条件去通知不同的观察者就得需要在通知方法上做条件过滤
JDK中提供了观察者模式实现的接口:
事物类可继承 java.util.Observable 类作为 被观察对象,此类对状态更新设置更精确,更安全
观察者类可实现 java.util.Observer 接口 作为观察者对象
推模型:将数据推送给观察者,有限制性,不利于复用
拉模型:类推模型,将事物自身传递给观察者,由观察者从中取值
(1)事物与观察者的关系,可以是一对多,也可能是多对多
(2)观察者依赖于目标事物,反向则不行
(3)事物类的命名应以Subject结尾,观察者对象则以Oberserver结尾
(4)为了让观察者与事物状态保持一致,应当在事物状态更新后再通知观察者
(5)事物通知多个观察者的顺序是平行的,没有先后之分
(6)执行流程:创建事物 -> 注册观察者 -> 更新事物 -> 通知观察者
基本骨架:
Subject
abstract class Subject { private List<Observer> observerList = new ArrayList<>(); public void attach(Observer o){observerList.add(o);} public void detach(Observer o){observerList.remove(o);} public void inform(){observerList.forEach(o -> o.update(this));} }
Observer
interface Observer { void update(Subject subject); }
简单模拟实现:
具体事物
class ConstructSubject extends Subject { private String status; public String getStatus(){return status;} public void setStatus(String status){ this.status = status; this.inform(); // 事物发生变化,通知更新 } }
观察者实现
class ConstructObserver implements Observer { String status; @Override public void update(Subject subject) { this.status = ((ConstructSubject)subject).getStatus(); } }
总结:Subject在设计模式中占主动地位,Observer可辅助Subject进行额外功能处理
Subject : 观察源事物,可添加或删除自身观察者
Observer : 观察者,可接受事物的通知
当事物发生更新变动,则通知观察者做相应处理,另事物状态与观察者状态保持一致
创建、注册阶段
客户端操作
观察者实现的两种模式:
区别:
推模型假定目标知道观察者需要的数据
拉模型不知道目标对象需要什么数据,把自身传递给观察者,由观察者取值
推模型使观察者对象复用性比较差
使用观察者模式的情况
适用情况: