观察者模式(Observer)
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。
观察者模式的组成
抽象主题角色 具体主题角色
抽象观察者角色 具体观察者角色
个人理解:
观察者模式类似于一种广播机制,当被观察者的状态发生改变时,会通知观察者,从而根据被观察者状态做出响应。同时观察者模式也是一种任务分发机制,观察者就是任务的执行者。
观察者模式的关键在于被观察者内部维护着一个观察者列表,被观察者内有一个方法,当该方法被调用时,就会调用观察者对应的方法。从表面上看,就像是这些方法被自动调用了一般。本质上则是被观察者方法的调用。
Java里的AWT是如何使用观察者模式的?
import java.awt.BorderLayout; import java.awt.Button; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestButton { public static void main(String[] args) { Frame frame = new Frame("Button"); Button button = new Button("Click"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println(e.getActionCommand()); } }); frame.add(button, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } }
这里使用java.awt.Button这个组件来分析一下。
从观察者模式的组成来看,这是一个具体主题角色。它有一个方法addActionListener(),接收一个实现ActionListener接口的类的实例,这个实例就是一个观察者,这个方法就向被观察者button注册了一个监听器(观察者)。文档中是这样写的:
When a button is pressed and released, AWT sends an instance of
ActionEvent
to the button, by callingprocessEvent
on the button. The button‘sprocessEvent
method receives all events for the button; it passes an action event along by calling its ownprocessActionEvent
method. The latter method passes the action event on to any action listeners that have registered an interest in action events generated by this button.
翻译过来就是:当在button上出现一个点击事件,AWT就会生成一个ActionEvent的实例,并调用button的processEvent方法:
protected void processEvent(AWTEvent e) { if (e instanceof ActionEvent) { processActionEvent((ActionEvent)e); return; } super.processEvent(e); }
这个方法对于单击按钮来说就会调用processActionEvent方法:
protected void processActionEvent(ActionEvent e) { ActionListener listener = actionListener; if (listener != null) { listener.actionPerformed(e); } }
而processActionEvent最终会调用注册到这个button上的actionListener上的actionPerformed方法,并将ActionEvent作为参数进行传递。这就是一次完整的方法调用过程。
不过看到这里我还有个疑问,就是被观察者内部会维护一个观察者列表,当一个事件发生时被观察者会调用所有已注册观察者的特定方法。但是Button的源码里只有这样一句:
transient ActionListener actionListener;
也就是说从表面上看,Button类内部只维护着一个ActionListener接口的实例,那么它究竟是如何实现添加多个观察者,并调用它们的方法的呢?继续跟进代码:
// Button.java public synchronized void addActionListener(ActionListener l) { if (l == null) { return; } actionListener = AWTEventMulticaster.add(actionListener, l); newEventsOnly = true; } // AWTEventMulticaster.java public static ActionListener add(ActionListener a, ActionListener b) { return (ActionListener)addInternal(a, b); } // AWTEventMulticaster.java protected static EventListener addInternal(EventListener a, EventListener b) { if (a == null) return b; if (b == null) return a; return new AWTEventMulticaster(a, b); }
这样就清楚了,原来是通过AWTEventMulticaster这个类封装了具体的actionListener信息,调用的时候递归调用就可以了。
// AWTEventMulticaster.java public void actionPerformed(ActionEvent e) { ((ActionListener)a).actionPerformed(e); ((ActionListener)b).actionPerformed(e); }
以上就是Java AWT使用观察者模式的原理
本文出自 “木叶的思考” 博客,请务必保留此出处http://muye12921.blog.51cto.com/5008231/1971128
原文地址:http://muye12921.blog.51cto.com/5008231/1971128