观察者模式:又叫发布-订阅模式,这里面有两个最重要的元素,一个是观察者,一个是被观察者,观察者的行为依赖于被观察者的状态,或者说当被观察对象(事件源对象)的状态改变时,会影响到观察者的行为。UML图以下:
其中,Source类是被观察者,它把全部对观察者对象的引用文件存在了一个集合,每一个被观察者均可以有任何数量的观察者。Observer类是抽象观察者,为全部的具体观察者定义一个接口,在获得被观察者的通知时作出相应的操做;当Source内部的状态发生改变时,给全部登记过的观察者发出通知(传入一个event,也就是将状态变化封装为一个事件);Observer1和Observer2具体观察者实现抽象观察者角色所要求的行为,以便使自己的状态与被观察者的状态相协同javascript
关联行为场景
事件多级触发场景java
在这里,我使用一个毕竟简单的例子介绍一下,好比java awt中的事件,当窗口上的按钮被点击的时候,事件监听器打印相应的内容,在这个当中,咱们模仿一下awt的事件机制:数组
首先定义一个观察者数组,并实现增、删及通知操做。它的职责很简单,就是定义谁能观察,谁不能观察ide
class Button{ private List<ActionListener> actionListeners = new ArrayList<>(); //当按钮被按下,通知观察者,传入事件对象,观察者作出相应的操做 public void buttonPressed(){ ActionEvent e = new ActionEvent(System.currentTimeMillis(), this); for(int i = 0; i< actionListeners.size(); i++) { actionListeners.get(i).actionPerformed(e); } } public void addActionListerner(ActionListener listener){ actionListeners.add(listener); } public void delActionListerner(ActionListener listener){ actionListeners.remove(listener); } }
观察者通常是一个接口,每个实现该接口的实现类都是具体观察者ui
interface ActionListener { public void actionPerformed(ActionEvent e); }
这里解释一下为何定义一个事件对象,有时候咱们可能只是简单的通知一下观察者,不须要传太多东西,可是大部分时候可能咱们的观察者还须要知道更多的东西,好比事件源,若是咱们的观察者须要调用被观察者的方法,那么咱们在这个事件对象当中拿到被观察者对象,就能够直接调用它的方法了this
class ActionEvent{ long when; Object source; public ActionEvent(long when, Object source){ super(); this.when = when; this.source = source; } public long getWhen() { return when; } public Object getSource() { return source; } }
class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("button pressed!"); } } class MyActionListener2 implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("button pressed 2!"); } }
public class Test { public static void main(String[] args) { //事件源对象/被观察者 Button button = new Button(); //观察 button.addActionListerner(new MyActionListener()); button.addActionListerner(new MyActionListener2()); //开始活动 button.buttonPressed(); } }
总结:观察者模式的应用比较普遍,在这种ui上面的事件机制,如awt,javascript的按钮点击事件等,它还能够跟责任链模式结合使用,将具体的观察者串成一条链,接收到通知的时候在链中去执行spa
Observer、Listener、Hook、Callback全都是观察者模式code