Observer观察者模式

简介:

观察者模式:又叫发布-订阅模式,这里面有两个最重要的元素,一个是观察者,一个是被观察者,观察者的行为依赖于被观察者的状态,或者说当被观察对象(事件源对象)的状态改变时,会影响到观察者的行为。UML图如下:
image
其中,Source类是被观察者,它把所有对观察者对象的引用文件存在了一个集合,每个被观察者都可以有任何数量的观察者。Observer类是抽象观察者,为所有的具体观察者定义一个接口,在得到被观察者的通知时做出相应的操作;当Source内部的状态发生改变时,给所有登记过的观察者发出通知(传入一个event,也就是将状态变化封装为一个事件);Observer1和Observer2具体观察者实现抽象观察者角色所要求的行为,以便使本身的状态与被观察者的状态相协同

使用场景:

关联行为场景
事件多级触发场景

模式实例:

在这里,我使用一个毕竟简单的例子介绍一下,比如java awt中的事件,当窗口上的按钮被点击的时候,事件监听器打印相应的内容,在这个当中,我们模仿一下awt的事件机制:

1、Button(事件源对象/被观察者)

首先定义一个观察者数组,并实现增、删及通知操作。它的职责很简单,就是定义谁能观察,谁不能观察

class Button{
    private List 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);
 }
}

2、ActionListener抽象观察者

观察者一般是一个接口,每一个实现该接口的实现类都是具体观察者

interface ActionListener {
    public void actionPerformed(ActionEvent e);
}

3、ActionEvent发布的事件对象

这里解释一下为什么定义一个事件对象,有时候我们可能只是简单的通知一下观察者,不需要传太多东西,但是大部分时候可能我们的观察者还需要知道更多的东西,比如事件源,如果我们的观察者需要调用被观察者的方法,那么我们在这个事件对象当中拿到被观察者对象,就可以直接调用它的方法了

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;
 }
}

4、具体观察者

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!");
 }
}

5、客户端

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的按钮点击事件等,它还可以跟责任链模式结合使用,将具体的观察者串成一条链,接收到通知的时候在链中去执行

Observer、Listener、Hook、Callback全都是观察者模式

你可能感兴趣的:(java)