7设计模式 之 观察者 和监听器的区别

GOF设计模式中有一种叫做观察者模式(Observer),属于行为型模式。又叫发布-订阅(Publish/Subscribe)模式、模型-视图 (Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个 主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。http://zoroeye.iteye.com/blog/2100318 

观察者模式被称为是模式中的皇后,而且java jdk也对它做了实现,可见该设计模式的重要位置。在图形化设计的软件中,为了实现视图和事件处理的分离,大多都采用了 Observer模式,比如java的Swing。现实的应用系统中也有好多应用,比如spring框架的初始化会触发很多事件,监听者可以根据自己订阅的事件作出自己的反应。 

jdk不仅提供了Observable类、Observer接口支持观察者模式,而且也提供了EventObject类、EventListener接口来支持事件监听模式,虽然两者属于同一类型模式,都属于回调机制,主动推送消息,但使用场景有些区别。 

1. 事件-监听机制 
事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法。 
7设计模式 之 观察者 和监听器的区别

2. 观察者模式 
观察者(Observer)相当于事件监听者(监听器),被观察者(Observable)相当于事件源和事件,执行逻辑时通知observer即可触发oberver的update,同时可传被观察者和参数。简化了事件-监听模式的实现。 
7设计模式 之 观察者 和监听器的区别

3.对比 

(1) 从uml图上也可以看出,Observer的实现相对简单,event-listener需要实现三个角色,observer-observable需要实现两个角色。 

(2)Observable的api已经把对观察者的注册,删除,监听者队列、通知方法 都实现等定义好了,而且是线程安全的。而event-listener需要使用者自己实现。 

(3)两者都需要自己定义并实现触发事件的通知。但Observable需要注意要在通知Observer之前调用jdk提供的setChanged()。 

(4)event-listener是传统的c/s界面事件模型,分事件源和事件(状态)角色,事件源要经过事件的包装、成为事件的属性之一再传递给事件监听/处理者,这个事件监听者就相当于观察者。Observer更简洁一些。两者在思想上是统一的,很多框架仍然使用了event-listener模式,比如spring框架的ApplicationEvent,ApplicationListener



基于jdk 的接口实现的观察者模式

  1. //观察者   
  2. class Watcher implements java.util.Observer {   
  3.   public void update(java.util.Observable obj, Object arg) {   
  4.     System.out.println("Update() called, count is "    
  5.                                 + ((Integer) arg).intValue());   
  6. }   
  7. }   
  8.            
  9. //被观察者   
  10. class BeingWatched extends java.util.Observable {   
  11.     void counter(int period) {   
  12.         for(; period>=0; period-- ) {   
  13.                 setChanged();   
  14.                 notifyObservers(new Integer(period));   
  15.                 try {   
  16.                         Thread.sleep(100);   
  17.                 } catch( InterruptedException e) {   
  18.                   System.out.println("Sleep interrupeted" );   
  19.                 }   
  20.         }   
  21. }   
  22. };   
  23.   
  24. //演示   
  25. public class ObserverDemo {   
  26.     public static void main(String[] args) {   
  27.         BeingWatched beingWatched = new BeingWatched();//受查者   
  28.         Watcher watcher = new Watcher();//观察者   
  29.         beingWatched.addObserver(watcher);   
  30.         beingWatched.counter(10);   
  31.     }   
  32. }