简介
观察者模式(Observer Pattern):定义对象之间一对多的依赖关系,当一个对象的状态发生改变时,相关的依赖对象都得到通知并自动更新。
- 解决多个对象之间的联动问题,这些观察者之间无需直接关系。又称发布-订阅模式、模型-视图模式、源-监听器模式、从属者模式。
结构和实现
- 角色包括:
- 目标:被观察的对象,包含观察者的集合和管理观察者的方法,也包括通知观察者的方法。可以是抽象类或者具体类。
- 具体目标:目标的子类,实现通知方法,特定时刻发布通知。也可能包含某些状态属性。如果无需扩展目标,可省略。
- 观察者:声明更新的方法,一般为接口。
- 具体观察者:实现更新方法,也可能包含具体目标的引用,获取状态信息。
- 观察者模式结构。
实例
- 开发多人联机对战游戏,多个玩家可以加入一个战队,战队中一个人遭到攻击,则通知其他盟友,其他盟友进行支援。
- 玩家遭受攻击后,实现两次对象之间的联动。
Player.beAttacked() --> AllyControlCenter.notifyObserver() -->Player.help()
优缺点和适用范围
- 优点:
- 表示层和逻辑层分离。通过消息更新机制传递,抽象更新接口使得可以联系不同的具体观察者表示层。
- 目标和观察者松耦合。目标只需要维持抽象观察者的集合。
- 支持广播通信。对所有注册的观察者通知,简化一对多的设计。
- 易增加观察者。具体观察者实现抽象观察者接口,并且互相之间没有直接关联,无需修改源码。
- 缺点:
- 通知对象消耗时间。特别是直接和间接观察者多时,通知所有对象消耗时间明显。
- 可能循环依赖。观察者和目标如果循环依赖,循环调用会导致系统崩溃。
- 无法知道目标如何变化。观察者只知道目标发生了变化,不能知道如何发生了变化。
- 适用环境:
- 抽象模型有两个方面,可以将他们封装在两个观察者中,独立的改变和复用。
- 一个对象改变导致多个对象改变,但是不知道具体是哪些对象。
- 需要创建触发链,A影响B,B影响C。
jdk中的应用
- java.util支持观察者模式,Observable类是目标,Observer接口是观察者。