【观察者模式】
也叫作发布/订阅模式,使用较为频繁。
定义了对象间一种一对多的依赖关系,当一个对象改变状态时,则所有依赖于它的对象都会得到通知并被自动更新。
观察者模式由以下几个角色组成:
* Subject 被观察者
定义被观察者必须实现的职责,他必须能够动态地增阿基、取消观察者。一般是抽象类或实现类,仅仅完成作为被观察者必须实现的职责:管理观察者+通知观察者。
* ConcreteSubject具体的被观察者
定义观察者自己的业务逻辑,同时定义对哪些事件进行通知。
* Observer 观察者
观察者接收到消息后,即进行update(更新方法)操作,对接收到的消息进行处理。
* ConcreteObserver具体的观察者
每个具体观察者在接受到消息后的处理反应是不一样的,各个观察者有自己的处理逻辑。
【观察者模式 例子】
package com.Higgin.Observer; import java.util.ArrayList; import java.util.List;/*** 电视观众接口 */ interface Viewer{public void feel(String show); } /*** 年轻观众*/ class YongViewer implements Viewer{@Overridepublic void feel(String show) {System.out.println("年轻人:感觉《"+show+"》很棒!");} } /*** 老年观众*/ class OldViewer implements Viewer{@Overridepublic void feel(String show) {System.out.println("老年人:感觉《"+show+"》一般!");} } /*** 抽象电视节目*/ abstract class TVProgrammer{//用来保存 注册的电视观众对象private List<Viewer> viewers=new ArrayList<Viewer>();//注册一个电视观众public void attach(Viewer v){this.viewers.add(v);}//删除一个电视观众public void detach(Viewer v){this.viewers.remove(v);}//通知所有注册的电视观众public void notifyViewers(String show){for(Viewer v:viewers){v.feel(show);}} }/*** 具体的娱乐电视节目*/ class HappyTVProgrammer extends TVProgrammer{//切换不同的娱乐节目public void change(String newShow){super.notifyViewers(newShow); //调用父类的通知方法 } }public class TestObserver {public static void main(String[] args) {Viewer yong=new YongViewer(); //一个年轻观众Viewer old=new OldViewer(); //一个老年观众HappyTVProgrammer tvp=new HappyTVProgrammer(); //娱乐电视节目tvp.attach(yong); //注册一个年轻人tvp.attach(old); //注册一个老年人tvp.notifyViewers("极限挑战");System.out.println("=============================");tvp.detach(old); //老人不爱看,解除tvp.change("奔跑吧,兄弟!");} }
【运行结果】
【观察者模式 优点】
* 观察者和被观察者之间是抽象耦合的
不管是增加观察者还是被观察者都非常容易,而且在java中已经实现了抽象层级的定义,在系统扩展方面应用良好。
* 建立了一套触发机制
根据单一职责原则,每个类的职责是单一的,如A事件触发B事件,B事件触发C事件...这是一个触发机制,形成一个触发链,观察者模式可以实现这里的链条形式。
【观察者模式 缺点】
要考虑开发效率和运行效率的问题,一个被观察者,多个观察者,开发和调试较为复杂,而且在JAVA中消息通知默认是顺序执行的,一个观察者卡壳,会影响整体的执行效率。这种情况一般会采用异步的方式。
【观察者模式 使用场景】
* 关联行为场景,注意关联行为是可拆分的,而不是“组合”关系。
* 事件多级触发场景。
* 跨系统的消息交换场景。