复习设计模式,看到observer观察者模式,说法是该模式和iterator迭代器模式类似已经被整合进jdk,但是jdk提供了两种接口:
一、java.util.Observer —— 观察者接口 对应:
java.util.Observable ——受查者根类
二、java.util.EventListener —— 事件监听/处理接口 对应:
java.util.EventObject —— 事件(状态)对象根类
研究了一下发现这两种接口的目的、功能其实是一样的(仅在事件模型的结构上有些许差异),先看EventListener事件监听器模式:
1、首要定义事件源对象(事件源相当于单击按钮事件当中的按钮对象、属于被监听者):
2、其次定义事件(状态)对象(该事件对象包装了事件源对象、作为参数传递给监听器、很薄的一层包装类):
3、最后定义我们的事件侦听器接口如下:
4、测试代码:
再看Observer观察者模式:
Observer和EventListener的区别仅仅在于它提前声明了事件处理方法:
update(Observable o, Object arg)
Observer模式当中不存在对应EventObject的角色,Observable被观察者就兼具了source事件源和EventObject事件对象两种角色,模型更简洁。
Observable被观察者根类就持有了观察者队列,也定义了类似notifyDemoEvent()的notifyObservers()方法...
一、java.util.Observer —— 观察者接口 对应:
java.util.Observable ——受查者根类
二、java.util.EventListener —— 事件监听/处理接口 对应:
java.util.EventObject —— 事件(状态)对象根类
研究了一下发现这两种接口的目的、功能其实是一样的(仅在事件模型的结构上有些许差异),先看EventListener事件监听器模式:
1、首要定义事件源对象(事件源相当于单击按钮事件当中的按钮对象、属于被监听者):
- public class DemoSource {
- private Vector repository = new Vector();//监听自己的监听器队列
- public DemoSource(){}
- public void addDemoListener(DemoListener dl) {
- repository.addElement(dl);
- }
- public void notifyDemoEvent() {//通知所有的监听器
- Enumeration enum = repository.elements();
- while(enum.hasMoreElements()) {
- DemoListener dl = (DemoListener)enum.nextElement();
- dl.handleEvent(new DemoEvent(this));
- }
- }
- }
2、其次定义事件(状态)对象(该事件对象包装了事件源对象、作为参数传递给监听器、很薄的一层包装类):
- public class DemoEvent extends java.util.EventObject {
- public DemoEvent(Object source) {
- super(source);//source—事件源对象—如在界面上发生的点击按钮事件中的按钮
- //所有 Event 在构造时都引用了对象 "source",在逻辑上认为该对象是最初发生有关 Event 的对象
- }
- public void say() {
- System.out.println("This is say method...");
- }
- }
3、最后定义我们的事件侦听器接口如下:
- public interface DemoListener extends java.util.EventListener {
- //EventListener是所有事件侦听器接口必须扩展的标记接口、因为它是无内容的标记接口、
- //所以事件处理方法由我们自己声明如下:
- public void handleEvent(DemoEvent dm);
- }
4、测试代码:
- //定义具体的事件监听器:
- public class DemoListener1 implements DemoListener {
- public void handleEvent(DemoEvent de) {
- System.out.println("Inside listener1...");
- de.say();//回调
- }
- }
- public class TestDemo {
- DemoSource ds;
- public TestDemo(){
- try{
- ds = new DemoSource();
- //将监听器在事件源对象中登记:
- DemoListener1 l1 = new DemoListener1();
- ds.addDemoListener(l1);
- ds.addDemoListener(new DemoListener() {
- public void handleEvent(DemoEvent event) {
- System.out.println("Method come from 匿名类...");
- }
- });
- ds.notifyDemoEvent();//触发事件、通知监听器
- }catch(Exception ex) {ex.printStackTrace();}
- }
- public static void main(String args[]) {
- new TestDemo();
- }
- }
再看Observer观察者模式:
Observer和EventListener的区别仅仅在于它提前声明了事件处理方法:
update(Observable o, Object arg)
Observer模式当中不存在对应EventObject的角色,Observable被观察者就兼具了source事件源和EventObject事件对象两种角色,模型更简洁。
Observable被观察者根类就持有了观察者队列,也定义了类似notifyDemoEvent()的notifyObservers()方法...
除了结构有差异外实在看不出Observer观察者模式和EventListener事件监听/处理模式的不一样!请教二者还有什么差异吗?
也贴出来Observer模式演示代码来对比:
- //观察者
- class Watcher implements java.util.Observer {
- public void update(java.util.Observable obj, Object arg) {
- System.out.println("Update() called, count is "
- + ((Integer) arg).intValue());
- }
- }
- //被观察者
- class BeingWatched extends java.util.Observable {
- void counter(int period) {
- for(; period>=0; period-- ) {
- setChanged();
- notifyObservers(new Integer(period));
- try {
- Thread.sleep(100);
- } catch( InterruptedException e) {
- System.out.println("Sleep interrupeted" );
- }
- }
- }
- };
- //演示
- public class ObserverDemo {
- public static void main(String[] args) {
- BeingWatched beingWatched = new BeingWatched();//受查者
- Watcher watcher = new Watcher();//观察者
- beingWatched.addObserver(watcher);
- beingWatched.counter(10);
- }
- }
原来这两种api可以说都是基于:订阅-发布模式的事件/消息通知模式,二者应该都算是“推”方式吧,就是被监控者将消息通知给所有监控者。
1、订阅:Observable.addObserver;
事件源.addDemoListener(这个方法是自己定义的)。
2、发布:Observable需要两步:setChanged()、notifyObservers(newValue);
事件源.notifyDemoEvent()(这个方法也是自己定义的)。
有人说Observer是设计模式中的皇后,很多系统级实现都是这种方式,我觉得是不是搞混了,因为我看java.util.Observer的api没什么下级接口或实现类。
反倒是相似的java.util.EventListener有大量下级接口和实现类,著名的包括:
java.beans.PropertyChangeListener
javax.servlet.http.HttpSessionListener...
以及java界面api里的很多...
这么看EventListener比Observer应用多得多,我猜想是否是因为EventListener的限制较少、没有规定事件处理方法名、比如HttpSessionListener就根据自己的应用领域定义事件处理方法:
sessionCreated(HttpSessionEvent se) 和
sessionDestroyed(HttpSessionEvent se)
如果用Observer就只能叫update了。
1、订阅:Observable.addObserver;
事件源.addDemoListener(这个方法是自己定义的)。
2、发布:Observable需要两步:setChanged()、notifyObservers(newValue);
事件源.notifyDemoEvent()(这个方法也是自己定义的)。
有人说Observer是设计模式中的皇后,很多系统级实现都是这种方式,我觉得是不是搞混了,因为我看java.util.Observer的api没什么下级接口或实现类。
反倒是相似的java.util.EventListener有大量下级接口和实现类,著名的包括:
java.beans.PropertyChangeListener
javax.servlet.http.HttpSessionListener...
以及java界面api里的很多...
这么看EventListener比Observer应用多得多,我猜想是否是因为EventListener的限制较少、没有规定事件处理方法名、比如HttpSessionListener就根据自己的应用领域定义事件处理方法:
sessionCreated(HttpSessionEvent se) 和
sessionDestroyed(HttpSessionEvent se)
如果用Observer就只能叫update了。