程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java不雅察者形式完成和java不雅察者形式演變

java不雅察者形式完成和java不雅察者形式演變

編輯:關於JAVA

java不雅察者形式完成和java不雅察者形式演變。本站提示廣大學習愛好者:(java不雅察者形式完成和java不雅察者形式演變)文章只能為提供參考,不一定能成為您想要的結果。以下是java不雅察者形式完成和java不雅察者形式演變正文


簡略的不雅察者形式完成


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外部的一切狀況。
如許我持續演變代碼為上面這個版本,留意我這裡沒有很過細地斟酌並提問題。


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接口。

JDK尺度類完成不雅察者形式


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被監聽者


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

// 監聽接口,回調函數,Client注冊監聽時須要供給回調函數完成
public interface SchedulerListener {

 void jobScheduled(Trigger trigger);

 void jobUnScheduled(Trigger trigger);

}

Trigger

// 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

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

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved