posts - 51, comments - 17, trackbacks - 0, articles - 9
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          java模式之觀察者模式

          Posted on 2007-03-24 17:03 chenweicai 閱讀(879) 評論(0)  編輯  收藏
           觀察者模式是對象的行為模式,顧名思義,即存在觀察者和被觀察者。?觀察者模式可以讓多個觀察者同時監聽同一個被觀察對象,當被觀察對象發生變化時,并通知所有觀察者,使各個觀察者能作出相應的響應。適當地運用觀察者模式,能提高自身代碼的設計水平。

            觀察者模式理解和編碼都比較簡單,通常包括以下步驟:

            1. 設計觀察者接口類;
            2. 觀察者類實現該接口;
            3. 設計被觀察者抽象類,該類中提供一些方法,如:添加觀察者對象,刪除觀察者對象,把事件通知給各個觀察者對象;
            4. 設計被觀察者類,繼承被觀察者抽象類,在該類中,可以根據需要在該類中,可以定義方法:被觀察者是否發生變化

            以上四步,即完成了觀察者模式的設計。下面代碼分類進行描述以上步驟:

          package Observer;

          import java.util.Enumeration;
          import java.util.Vector;

          abstract public class Subject {

          ?private Vector observersVector = new java.util.Vector();
          ?
          ?public void attach(Observer observer){
          ??observersVector.addElement(observer);
          ??System.out.println("Attached an observer.");
          ?}
          ?
          ?public void detach(Observer observer){
          ??observersVector.removeElement(observer);
          ?}
          ?
          ?public void notifyObservers(){
          ??java.util.Enumeration enumeration = observers();
          ??while(enumeration.hasMoreElements()){
          ???System.out.println("Before notifying");
          ???((Observer)enumeration.nextElement()).update();
          ??}
          ?}
          ?
          ?public Enumeration observers(){
          ??return ((java.util.Vector)observersVector.clone()).elements();
          ?}
          }


          package Observer;

          public class ConcreteSubject extends Subject{

          ?private String state;
          ?
          ?public void change(String newState){
          ??state = newState;
          ??this.notifyObservers();
          ?}
          }


          package Observer;

          public interface Observer {

          ?void update();
          }


          package Observer;

          public class ConcreteObserver implements Observer{
          ?
          ?public void update(){
          ??System.out.println("I am notified.");
          ?}

          }


          package Observer;

          public class Client {

          ?private static ConcreteSubject subject;
          ?private static Observer observer1;
          ?private static Observer observer2;
          ?
          ?public static void main(String[] args){
          ??subject = new ConcreteSubject();
          ??observer1 = new ConcreteObserver();
          ??observer2 = new ConcreteObserver();
          ??
          ??subject.attach(observer1);
          ??subject.attach(observer2);
          ??
          ??subject.change("new state");
          ?}
          }


          運行結果是:

          Attached an observer.
          Attached an observer.
          Before notifying
          I am notified.
          Before notifying
          I am notified.


          在java中提供了Observerable類和Observer接口來實現觀察者模式

          public class Observable
          extends Object

          此類表示模型視圖范例中的 observable 對象,或者說“數據”。可將其子類化,表示應用程序想要觀察的對象(即被觀察者)。

          一個 observable 對象可以有一個或多個觀察者。觀察者可以是實現了 Observer 接口的任意對象。一個 observable 實例改變后,調用 ObservablenotifyObservers 方法的應用程序會通過調用觀察者的 update 方法來通知觀察者該實例發生了改變。

          未指定發送通知的順序。Observable 類中所提供的默認實現將按照其注冊的重要性順序來通知 Observers,但是子類可能改變此順序,從而使用非固定順序在單獨的線程上發送通知,或者也可能保證其子類遵從其所選擇的順序。

          注意,此通知機制與線程無關,并且與 Object 類的 waitnotify 機制完全獨立。

          新創建一個 observable 對象時,其觀察者集合是空的。當且僅當 equals 方法為兩個觀察者返回 true 時,才認為它們是相同的。

          public interface Observer

          一個可在觀察者要得到 observable 對象更改通知時可實現 Observer 接口的類。?
          ?給個用java機制來實現觀察者模式的例子
          在java機制中Observable類相當于抽象主題角色,我們定義具體主題角色來繼承該類
          Observer 接口相當于抽象觀察者角色,我們定義具體觀察者角色來實現該接口
          所以這兩個抽象角色我們不用編寫了 只需編寫兩個具體角色

          //----具體觀察對象角色
          package Observer.javaObserver;

          import java.util.Observable;

          public class Product extends Observable{

          ?private String name;
          ?private float price;
          ?
          ?public String getName(){
          ??return name;
          ?}
          ?
          ?public void setName(String name){
          ??this.name = name;
          ??// 設置變化點
          ??setChanged();
          ??notifyObservers(name);//通知觀察者
          ?}

          ?public float getPrice() {
          ??return price;
          ?}

          ?public void setPrice(float price) {
          ??this.price = price;
          ??//設置變化點
          ??setChanged();
          ??notifyObservers(new Float(price));
          ?}
          ?
          ?public void saveToDb(){
          ??System.out.println("saveToDb");
          ?}
          }

          //------------ 兩個具體觀察者角色
          package Observer.javaObserver;

          import java.util.Observable;
          import java.util.Observer;

          public class NameObserver implements Observer {

          ?private String name = null;
          ?
          ?public void update(Observable obj, Object arg){
          ??if(arg instanceof String){
          ???name = (String)arg;
          ???System.out.println("NameObserver:name changed to " + name);
          ??}
          ?}
          }

          package Observer.javaObserver;

          import java.util.Observable;
          import java.util.Observer;

          public class PriceObserver implements Observer{

          ?private float price=0;
          ?
          ?public void update(Observable obj, Object arg){
          ??if(arg instanceof Float){
          ???price = ((Float)arg).floatValue();
          ???System.out.println("PriceObserver: price change to" + price);
          ??}
          ?}
          }

          //----測試程序

          package Observer.javaObserver;

          import java.util.Observer;

          public class Test {

          ?public static void main(String[] args){
          ??Product product = new Product();
          ??Observer nameObs = new NameObserver();
          ??Observer priceObs = new PriceObserver();
          ??
          ??product.addObserver(nameObs);
          ??product.addObserver(priceObs);
          ??
          ??product.setName("apple");
          ??product.setPrice(9.22f);
          ??
          ??product.setName("Apple");
          ??product.setPrice(9.88f);
          ??}
          }


          //---運行結果

          NameObserver:name changed to apple
          PriceObserver: price change to9.22
          NameObserver:name changed to Apple
          PriceObserver: price change to9.88




          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 惠州市| 靖江市| 扎兰屯市| 安达市| 承德县| 阳江市| 元朗区| 普陀区| 双流县| 汉源县| 南宫市| 天津市| 元江| 旺苍县| 白玉县| 商水县| 南康市| 泽州县| 安平县| 泸西县| 西充县| 灌云县| 乌恰县| 乐平市| 土默特右旗| 巫溪县| 新沂市| 隆昌县| 隆化县| 玉山县| 华坪县| 临朐县| 大邑县| 阿克苏市| 安远县| 武陟县| 佛山市| 武冈市| 壤塘县| 平果县| 南丰县|