源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

java观察者模式实现和java观察者模式演化

  • 时间:2022-11-25 22:20 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:java观察者模式实现和java观察者模式演化
[b]简单的观察者模式实现[/b]
[u]复制代码[/u] 代码如下:
import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; /**  * 观察者模式中用到了回调:  * A. 观察者将自己注册到被观察者的监听者列表,且观察者类自身提供了一个回调函数  * B. 被观察者(Observable或Subject)维护观察者列表,并且可以注册和解注册观察者  * C. 一旦被观察者状态发生改变,它可以调用notifyObservers(),这个方法将遍历观察者列表并逐个调用 观察者提供的回调函数  * @author will  *  */ public class SimpleObserverPattern {  public static void main(String[] args) {   SimpleObserverPattern sop = new SimpleObserverPattern();   List<IObserver> observers = new ArrayList<IObserver> ();   IObserver observerA = sop.new Observer("ObserverA");   IObserver observerB = sop.new Observer("ObserverB");   observers.add(observerA);   observers.add(observerB);   IObservable observable = sop.new Observable(observers);   observable.registerObserver(sop.new Observer("ObserverC"));   observable.changeState();   observable.close();  }  // 被观察者,有的地方叫Subject  interface IObservable {   void registerObserver(IObserver observer);   void unregisterObserver(IObserver observer);   void notifyObservers();   String getState();   void changeState();   void close();  }  class Observable implements IObservable {   private static final String NEW = "New";   private static final String CHANGED = "Changed";   private static final String CLOSED = "Closed";   private String state;   private List<IObserver> observers;   public Observable() {    this(null);   }   public Observable(List<IObserver> observers) {    if(observers == null) {     observers = new ArrayList<IObserver> ();    }     this.observers = Collections.synchronizedList(observers);     this.state = NEW;   }   @Override   public void registerObserver(IObserver observer) {    observers.add(observer);   }   @Override   public void unregisterObserver(IObserver observer) {    observers.remove(observer);   }   @Override   public void notifyObservers() {    Iterator<IObserver> iter = observers.iterator();    while(iter.hasNext()) {     iter.next().update(this);    }   }   @Override   public String getState() {    return state;   }   @Override   public void changeState() {    this.state = CHANGED;    notifyObservers();   }   @Override   public void close() {    this.state = CLOSED;    notifyObservers();   }  }  interface IObserver {   void update(IObservable observalbe);  }  class Observer implements IObserver {   private String name;   public Observer(String name) {    this.name = name;   }   @Override   public void update(IObservable observalbe) {    System.out.println(      String.format("%s receive observalbe's change, current observalbe's state is %s",         name, observalbe.getState()));   }  } }
上面的实现直接将被观察者对象作为回调函数参数,这样做很不优雅,在简单的场景可能奏效。 但事实上更多情况下,一个被观察者有很多种事件或者状态,而每个观察者可能感兴趣的事件或状态都不相同,或者为了信息隐藏的目的,不想让每个观察者都能访问到Observable内部的所有状态。 这样我继续演化代码为下面这个版本,注意我这里没有很细致地考虑并发问题。
[u]复制代码[/u] 代码如下:
import java.util.Collections; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; public class MultiEventObserverPattern {  public static void main(String[] args) {   MultiEventObserverPattern meop = new MultiEventObserverPattern();   IObservable observable = meop.new Observable();   IObserver observerA = meop.new Observer("ObserverA");   IObserver observerB = meop.new Observer("ObserverB");   // 注册感兴趣的事件   observable.registerObserver(observable.getEventA(), observerA);   observable.registerObserver(observable.getEventB(), observerB);   // 改变被观察者状态   observable.changeStateA();   observable.changeStateB();  }  interface IEvent {   void eventChange();   String getState();  }  class EventA implements IEvent {   private static final String INITIALIZED = "Initialized";   private static final String PENDING = "Pending";   private String state;   public EventA() {    this.state = INITIALIZED;   }   @Override   public void eventChange() {    System.out.println("EventA change");    this.state = PENDING;   }   @Override   public String toString() {    return "EventA";   }   @Override   public String getState() {    return state;   }  }  class EventB implements IEvent {   private static final String NEW = "New";   private static final String IDLE = "Idle";   private String state;   public EventB() {    this.state = NEW;   }   @Override   public void eventChange() {    System.out.println("EventB change");    this.state = IDLE;   }   @Override   public String toString() {    return "EventB";   }   @Override   public String getState() {    return state;   }  }  // 被观察者(Observable),有的地方叫Subject  interface IObservable {   void registerObserver(IEvent event, IObserver observer);   void unregisterObserver(IEvent event, IObserver observer);   // 通知观察者某个事件发生了   void notifyObservers(IEvent event);   void changeStateA();   void changeStateB();   IEvent getEventA();   IEvent getEventB();  }  class Observable implements IObservable {   private IEvent eventA;   private IEvent eventB;   private Hashtable<IEvent, Set<IObserver>> eventObserverMapping;   public Observable() {    this(null);   }   // 这里如果evenObserverMapping传入的某些Set<IObserver>是未被同步修饰的,那么也没办法   public Observable(Hashtable<IEvent, Set<IObserver>> eventObserverMapping) {    if(eventObserverMapping == null) {     eventObserverMapping = new Hashtable<IEvent, Set<IObserver>> ();    }    this.eventObserverMapping = new Hashtable<IEvent, Set<IObserver>> ();    this.eventA = new EventA();    this.eventB = new EventB();   }   @Override   public void registerObserver(IEvent event, IObserver observer) {    Set<IObserver> observers = eventObserverMapping.get(event);    if(observers == null) {     observers = Collections.synchronizedSet(new HashSet<IObserver> ());     observers.add(observer);     eventObserverMapping.put(event, observers);    }    else {     observers.add(observer);    }   }   @Override   public void unregisterObserver(IEvent event, IObserver observer) {    Set<IObserver> observers = eventObserverMapping.get(event);    if(observers != null) {     observers.remove(observer);    }   }   @Override   public void notifyObservers(IEvent event) {    Set<IObserver> observers = eventObserverMapping.get(event);    if(observers != null && observers.size() > 0) {     Iterator<IObserver> iter = observers.iterator();     while(iter.hasNext()) {      iter.next().update(event);     }    }   }   @Override   public void changeStateA() {    // 改变状态A会触发事件A    eventA.eventChange();    notifyObservers(eventA);   }   @Override   public void changeStateB() {    // 改变状态B会触发事件B    eventB.eventChange();    notifyObservers(eventB);   }   @Override   public IEvent getEventA() {    return eventA;   }   @Override   public IEvent getEventB() {    return eventB;   }  }  interface IObserver {   void update(IEvent event);  }  class Observer implements IObserver {   private String name;   public Observer(String name) {    this.name = name;   }   @Override   public void update(IEvent event) {    System.out.println(      String.format("%s receive %s's change, current observalbe's state is %s",         name, event, event.getState()));   }  } }
似乎看起来挺完美了,但还是不够完美。因为事件被硬编码为被观察者类的属性。这样事件类型在编译时期就被定死了,如果要增加新的事件类型就不得不修改IObservable接口和Observable类,这大大削减了灵活性。 相当于被观察者耦合于这些具体的事件,那么我们如何来打破这个限制呢? 答案是引入一个新的组件,让那个组件来管理事件、观察者、被观察者之间的关系,事件发生时也由那个组件来调用观察者的回调函数。这也是一种解耦吧,有点类似Spring的IOC容器。 至于具体实现,我觉得Guava EventBus做得已经蛮好了,可以参考我前面提到的链接。 PS:本帖不是为Guava EventBus做广告,只是自己的思路一步步推进,逐渐地就和Guava EventBus的设计思路吻合了。 下面继续看看JDK标准类实现观察者模式的例子,然后分析下它的源码实现,要看的只有一个Observable类和一个Observer接口。 [b]JDK标准类实现观察者模式[/b]
[u]复制代码[/u] 代码如下:
import java.util.Observable; import java.util.Observer; /**  * 使用java.util包中的标准类实现观察者模式  * @author will  *  */ public class JDKObserverDemo {  public static void main(String[] args) {   JDKObserverDemo jod = new JDKObserverDemo();   // 被观察者   MyObservable myObservable = jod.new MyObservable("hello");   // 观察者   Observer myObserver = jod.new MyObserver();   // 注册   myObservable.addObserver(myObserver);   // 改变被观察者状态,触发观察者回调函数   myObservable.setValue("will");  }  class MyObservable extends Observable {   private String watchedValue;   // 被观察的值   public MyObservable(String watchedValue) {    this.watchedValue = watchedValue;   }   public void setValue(String newValue) {    if(!watchedValue.equals(newValue)) {     watchedValue = newValue;     setChanged();     notifyObservers(newValue);    }   }   @Override   public String toString() {    return "MyObservable";   }  }  class MyObserver implements Observer {   @Override   public void update(Observable o, Object arg) {    System.out.println(o + "'s state changed, argument is: " + arg);   }  } }
看了下JDK标准库中的Observer和Observable实现很简单,不想多说了。 下面是Quartz中的监听器实现。 QuartzScheduler被监听者
[u]复制代码[/u] 代码如下:
import java.util.ArrayList; import java.util.Date; import java.util.List; /**  * Quartz核心类,相当于Observable(被观察者)  * @author will  *  */ public class QuartzScheduler {  private ArrayList<SchedulerListener> internalSchedulerListeners = new ArrayList<SchedulerListener>(10); // private ArrayList<JobListener> interanlJobListeners = new ArrayList<JobListener>();   // 一个Observable可以包含多组监听器  public Date scheduleJob(Trigger trigger) {   if(trigger == null) {    return null;   }   System.out.println("Schedule job, trigger: " + trigger);   notifySchedulerListenersScheduled(trigger);   return new Date();  }  public void unScheduleJob(Trigger trigger) {   if(trigger == null) {    return;   }   System.out.println("Unschedule job, trigger: " + trigger);   notifyShedulerListenerUnScheduled(trigger);  }  // 注册SchedulerListener     public void addInternalSchedulerListener(SchedulerListener schedulerListener) {         synchronized (internalSchedulerListeners) {             internalSchedulerListeners.add(schedulerListener);         }     }     // 移除SchedulerListener     public boolean removeInternalSchedulerListener(SchedulerListener schedulerListener) {         synchronized (internalSchedulerListeners) {             return internalSchedulerListeners.remove(schedulerListener);         }     }     public List<SchedulerListener> getInternalSchedulerListeners() {         synchronized (internalSchedulerListeners) {             return java.util.Collections.unmodifiableList(new ArrayList<SchedulerListener>(internalSchedulerListeners));         }     }     public void notifySchedulerListenersScheduled(Trigger trigger) {      for(SchedulerListener listener: getInternalSchedulerListeners()) {       listener.jobScheduled(trigger);      }     }     public void notifyShedulerListenerUnScheduled(Trigger trigger) {      for(SchedulerListener listener: getInternalSchedulerListeners()) {       listener.jobUnScheduled(trigger);      }     } }
SchedulerListener
[u]复制代码[/u] 代码如下:
// 监听接口,回调函数,Client注册监听时需要提供回调函数实现 public interface SchedulerListener {  void jobScheduled(Trigger trigger);  void jobUnScheduled(Trigger trigger); }
Trigger
[u]复制代码[/u] 代码如下:
// Trigger public class Trigger {  private String triggerKey;  private String triggerName;  public Trigger(String triggerKey, String triggerName) {   this.triggerKey = triggerKey;   this.triggerName = triggerName;  }  public String getTriggerKey() {   return triggerKey;  }  public void setTriggerKey(String triggerKey) {   this.triggerKey = triggerKey;  }  public String getTriggerName() {   return triggerName;  }  public void setTriggerName(String triggerName) {   this.triggerName = triggerName;  }  public String toString() {   return String.format("{triggerKey: %s, triggerName: %s}", triggerKey, triggerName);  } }
Test
[u]复制代码[/u] 代码如下:
public class Test {  public static void main(String[] args) {   QuartzScheduler qs = new QuartzScheduler();   SchedulerListener listenerA = new SchedulerListener() {    @Override    public void jobUnScheduled(Trigger trigger) {     System.out.println("listenerA job unscheduled: " + trigger.getTriggerName());    }    @Override    public void jobScheduled(Trigger trigger) {     System.out.println("listenerA job scheduled: " + trigger.getTriggerName());    }   };   SchedulerListener listenerB = new SchedulerListener() {    @Override    public void jobUnScheduled(Trigger trigger) {     System.out.println("listenerB job unscheduled: " + trigger.getTriggerName());    }    @Override    public void jobScheduled(Trigger trigger) {     System.out.println("listenerB job scheduled: " + trigger.getTriggerName());    }   };   // 注册Scheduler Listener   qs.addInternalSchedulerListener(listenerA);   qs.addInternalSchedulerListener(listenerB);   Trigger triggerA = new Trigger("Key1", "triggerA");   Trigger triggerB = new Trigger("Key2", "triggerB");   qs.scheduleJob(triggerA);   qs.scheduleJob(triggerB);   qs.unScheduleJob(triggerA);  } }
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部