程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 觀察者模式

觀察者模式

編輯:JAVA編程入門知識

  觀察者模式,以前看過,今天想了一下,似乎有點模糊了,回顧一下,再加之以筆記,以備……

  行為模式,為實現此模式,應該具備這幾個角色:被觀察的主題,觀察者。這是必須的!一般來說,為使構建的東西有一定的可用性,會進行進一步的分工。主題角色再分為抽象主題和具體主題,同樣滴劃分觀察者角色為抽象觀察者及具體觀察者角色。這就是將在此文中提及的 Subject, ConcreteSubject, Observer, ConcreteObserver。

  按照《JAVA 與模式》書來的,實現了最簡單的兩個版本。

  版本一:

  

/** 抽象主題角色,屬於被觀察者 */
  public interface Subject {
    /**
     * 登記一個新的觀察者對象
     */
    public void attach(Observer observer);
    /**
     * 刪除一個觀察者對象
     */
    public void detach(Observer observer);
    /**
     * 通知所有登記過的觀察者對象
     */
    void notifyObservers();
  }
  /** 具體主題角色,屬於被觀察者 */
  public class ConcreteSubject implements Subject {     
    private Vector observersVector = new Vector();
    /** 這裡省略了幾個方法的實現,無非是往向量中添加 Observer, 沒什麼好寫的 */  
    /**
     * 通知所有登記過的觀察者對象
     * 這裡和書有一點點的不一樣,我用的是 Iterator 接口來實現
     * 書上的是 Enumeration ,但大同小異。
     */
    public void notifyObservers() {
      Iterator it = observersVector.iterator();
      while(it.hasNext()) {
        ((Observer)it.next()).update();
      }
    }
  }
  /** 抽象觀察者角色 */
  public interface Observer {
    /**
     * 調用這個方法會更新自己
     */
    void update();
  }
  /** 具體觀察者角色 */
  public class ConcreteObserver implements Observer {
    /**
     * 調用這個方法會更新自己
     */
    public void update() {
      System.out.println(this + "  I am notified");
    }
  }

  客戶端的 main() 如下:

  

public static void main(String[] args) {
    Subject subject = new ConcreteSubject();
    Observer observer1 = new ConcreteObserver();
    Observer observer2 = new ConcreteObserver();
    subject.attach(observer1);
    subject.attach(observer2);
    subject.notifyObservers();
  }

  版本一的實現基本上與書上的沒有什麼不同,而版本二則有一點點的不一樣。版本二只改變了版本一中的兩個被觀察者的一些細節。在此貼上:

  

/**
   * 這是一個重量級的抽象主題角色,將子類的一些方法移至此
   * 增加了抽象類的重量而減少了具體主題類的分量
   */
  public abstract class Subject {     
    /**
     * 保存所有對觀察者對象的引用
     */
    private Vector observersVector = new Vector();
     
    /**
     * 更改主題的狀態
     *  在書上沒有該方法,為了在客戶端能夠用基類聲明對象,將該方法的聲明移至此
     */
    public abstract void change(String newState);
    /** 在這裡也把往主題角色中添加/刪除觀察者對象的方法省略了 */  
    /**
     * 通知所有登記過的觀察者對象
     */
    public void notifyObservers() {
      Iterator it = observersVector.iterator();
      while(it.hasNext()) {
          ((Observer)it.next()).update();
      }
    }
  }
  /**
   * 輕量級的具體主題類角色
   */
   public class ConcreteSubject extends Subject {
     
    private String state;
     
    /**
     * 更改主題的狀態
     */
    public void change(String newState) {
      state = newState;
      this.notifyObservers();     
    }
  }

  客戶端的代碼是完全一樣的。

  其實這樣一個模式是相對比較簡單的,當然,簡單並不意味著力量不大,呵呵。用另外一個形式來表示:

  public class 被觀察者 {public void 通知觀察者() {觀察者對象.有情況發生();}}

  public class 觀察者 {public void 有情況發生() {/* 在這裡做你想做的事情 *

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