熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

爪哇語言觀察者模式介紹

2022-06-13   來源: Java高級技術 

  簡單地說觀察者模式定義了一個一對多的依賴關系讓一個或多個觀察者對象監察一個主題對象這樣一個主題對象在狀態上的變化能夠通知所有的依賴於此對象的那些觀察者對象使這些觀察者對象能夠自動更新
  觀察者模式的結構
  觀察者(Observer)模式是對象的行為型模式又叫做發表訂閱(Publish/Subscribe)模式模型視圖(Model/View)模式收聽者(Source/Listener)模式或從屬者(Dependents)模式
  本模式的類圖結構如下
   
  圖觀察者模式的靜態結構可從類圖中看清楚 
  在觀察者模式裡有如下的角色
   抽象主題(Subject)角色主題角色把所有的觀察者對象的引用保存在一個列表裡每個主題都可以有任何數量的觀察者主題提供一個接口可以加上或撤銷觀察者對象主題角色又叫做抽象被觀察者(Observable)角色
   
  圖抽象主題角色有時又叫做抽象被觀察者角色可以用一個抽象類或者一個接口實現在具體的情況下也不排除使用具體類實現 
   抽象觀察者(Observer)角色為所有的具體觀察者定義一個接口在得到通知時更新自己
   
  圖抽象觀察者角色可以用一個抽象類或者一個接口實現在具體的情況下也不排除使用具體類實現 
   具體主題(ConcreteSubject)角色保存對具體觀察者對象有用的內部狀態在這種內部狀態改變時給其觀察者發出一個通知具體主題角色又叫作具體被觀察者角色
   
  圖具體主題角色通常用一個具體子類實現 
  .具體觀察者(ConcreteObserver)角色保存一個指向具體主題對象的引用和一個與主題的狀態相符的狀態具體觀察者角色實現抽象觀察者角色所要求的更新自己的接口以便使本身的狀態與主題的狀態自恰
   
  圖具體觀察者角色通常用一個具體子類實現 
  下面給出一個示意性實現的Java代碼首先在這個示意性的實現裡用一個Java接口實現抽象主題角色這就是下面的Subject接口
  public interface Subject
  {
  public void attach(Observer observer);
  public void detach(Observer observer);
  void notifyObservers();
  }
  代碼清單Subject接口的源代碼
  這個抽象主題接口規定出三個子類必須實現的操作即 attach() 用來增加一個觀察者對象detach() 用來刪除一個觀察者對象和notifyObservers() 用來通知各個觀察者刷新它們自己抽象主題角色實際上要求子類保持一個以所有的觀察者對象為元素的列表
  具體主題則是實現了抽象主題Subject接口的一個具體類它給出了以上的三個操作的具體實現從下面的源代碼可以看出這裡給出的Java實現使用了一個Java向量來保存所有的觀察者對象而 attach() 和 detach() 操作則是對此向量的元素增減操作
  import javautilVector;
  import javautilEnumeration;
  public class ConcreteSubject implements Subject
  public void attach(Observer observer)
  {
  observersVectoraddElement(observer);
  }
  public void detach(Observer observer)
  {
  observersVectorremoveElement(observer);
  }
  public void notifyObservers()
  {
  Enumeration enumeration = observers();
  while (enumerationhasMoreElements())
  {
  ((Observer)enumerationnextElement())update();
  }
  }
  public Enumeration observers()
  {
  return ((Vector) observersVectorclone())elements();
  }
  private Vector observersVector = new javautilVector();
  }
  代碼清單ConcreteSubject類的源代碼
  抽象觀察者角色的實現實際上是最為簡單的一個它是一個Java接口只聲明了一個方法即update()這個方法被子類實現後一被調用便刷新自己
  public interface Observer
  {
  void update();
  }
  代碼清單Observer接口的源代碼
  具體觀察者角色的實現其實只涉及update()方法的實現這個方法怎麼實現與應用密切相關因此本類只給出一個框架
  public class ConcreteObserver implements Observer
  {
  public void update()
  {
  // Write your code here
  }
  }
  代碼清單ConcreteObserver類的源代碼
  雖然觀察者模式的實現方法可以有設計師自己確定但是因為從AWT開始視窗系統的事件模型采用觀察者模式因此觀察者模式在Java語言裡的地位較為重要正因為這個原因Java語言給出了它自己對觀察者模式的支持因此本文建議讀者在自己的系統中應用觀察者模式時不妨利用Java語言所提供的支持
  Java語言提供的對觀察者模式的支持
  在Java語言的javautil庫裡面提供了一個Observable類以及一個Observer接口構成Java語言對觀察者模式的支持
  Observer接口
  這個接口只定義了一個方法update()當被觀察者對象的狀態發生變化時這個方法就會被調用這個方法的實現應當調用每一個被觀察者對象的notifyObservers()方法從而通知所有的觀察對象
   
  圖javautil提供的Observer接口的類圖 
  package javautil;
  public interface Observer
  {
  /**
  * 當被觀察的對象發生變化時這個方法會被調用
  */
  void update(Observable o Object arg);
  }
  代碼清單javautilObserver接口的源代碼
  Observable類
  被觀察者類都是javautilObservable類的子類javautilObservable提供公開的方法支持觀察者對象這些方法中有兩個對Observable的子類非常重要一個是setChanged()另一個是notifyObservers()第一個方法setChanged()被調用之後會設置一個內部標記變量代表被觀察者對象的狀態發生了變化第二個是notifyObservers()這個方法被調用時會調用所有登記過的觀察者對象的update()方法使這些觀察者對象可以更新自己
  javautilObservable類還有其它的一些重要的方法比如觀察者對象可以調用javautilObservable類的addObserver()方法將對象一個一個加入到一個列表上當有變化時這個列表可以告訴notifyObservers()方法那些觀察者對象需要通知由於這個列表是私有的因此javautilObservable的子對象並不知道觀察者對象一直在觀察著它們
   
  圖Java語言提供的被觀察者的類圖 
  被觀察者類Observable的源代碼
  package javautil;
  public class Observable
  {
  private boolean changed = false;
  private Vector obs;
  /** 用個觀察者構造一個被觀察者**/
  
  public Observable()
  {
  obs = new Vector();
  }
  /**
  * 將一個觀察者加到觀察者列表上面
  */
  public synchronized void addObserver(Observer o)
  {
  if (!ntains(o))
  {
  obsaddElement(o);
  }
  }
  /**
  * 將一個觀察者對象從觀察者列表上刪除
  */
  public synchronized void deleteObserver(Observer o)
  {
  obsremoveElement(o);
  }
  /**
  * 相當於 notifyObservers(null)
  */
  public void notifyObservers()
  {
  notifyObservers(null);
  }
  /**
  * 如果本對象有變化(那時hasChanged 方法會返回true)
  * 調用本方法通知所有登記在案的觀察者即調用它們的update()方法
  * 傳入this和arg作為參量
  */
  public void notifyObservers(Object arg)
  {
  /**
  * 臨時存放當前的觀察者的狀態參見備忘錄模式
  */
  Object[] arrLocal;
  synchronized (this)
  {
  if (!changed) return;
  arrLocal = obstoArray();
  clearChanged();
  }
  for (int i = arrLocallength; i>=; i)
  ((Observer)arrLocal[i])update(this arg);
  }
  /**
  * 將觀察者列表清空
  */
  public synchronized void deleteObservers()
  {
  obsremoveAllElements();
  }
  /**
  * 將已變化設為true
  */
  protected synchronized void setChanged()
  {
  changed = true;
  }
  /**
  * 將已變化重置為false
  */
  protected synchronized void clearChanged()
  {
  changed = false;
  }
  /**
  * 探測本對象是否已變化
  */
  public synchronized boolean hasChanged()
  {
  return changed;
  }
  /**
  * 返還被觀察對象(即此對象)的觀察者總數
  */
  public synchronized int countObservers()
  {
  return obssize();
  }
  }
  代碼清單
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27487.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.