posts - 73,  comments - 55,  trackbacks - 0

          按照“四人團”的說法,Observer模式的意圖是“定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新”。
          問題:當某個事件發生時,你需要向一系列對象發出通知,而這個對象的列表是不斷變化的。(而當依賴關系固定或幾乎固定時,加入Observer模式只會增加復雜性)

          簡單來說,Observer模式讓一個對象(觀察者,Observer)去監視另一個對象(目標,Subject);它使得目標和觀察者之間建立一種 "發布--訂閱"(publish-subscribe )的關系。通過Observer模式,觀察者可以向目標登記,表明自己要從目標接收事件。目標需要向觀察者通知事件時,只是簡單地將事件發給每一個觀察者。

          例如,有一個基于某種數據模型的電子表格。只要數據模型發生變化,電子表格就需要更新表格單元以及內嵌的圖表。這個例子中,目標是數據模型,觀察者是表格單元和圖表。當觀察者接收到數據模型已經變化的通知時,它們就更新自己。

          Observer模式的好處是:它解除了觀察者和目標之間的耦合關系。目標不需要知道它的觀察者的任何信息。相反,目標只是允許觀察者訂閱事件。當目標產生一個事件時,它簡單地將事件傳給每一個觀察者。

          看看下面的Java示例:

          public interface Subject {
          public void addObserver( Observer o );
          public void removeObserver( Observer o );
          }

          上面的代碼中,Subject接口定義了兩個方法(method),每個Subject都必須實現它們,以使Observer可以在Subject中增加或刪除自身。

          public interface Observer {
          public void update( Subject o );
          }

          Observer接口(如上)列出了一個方法(method),每個Observer都必須實現它,以使Subject可以發送更新消息給Observer。

          下面看看Subject的一個簡單的實現--IntegerDataBag:

          import java.util.ArrayList;
          import java.util.Iterator;

          public class IntegerDataBag implements Subject {

          private ArrayList list = new ArrayList();
          private ArrayList observers = new ArrayList();

          public void add( Integer i ) {
          list.add( i );
          notifyObservers();
          }

          public Iterator iterator() {
          return list.iterator();
          }

          public Integer remove( int index ) {
          if( index < list.size() ) {
          Integer i = (Integer) list.remove( index );
          notifyObservers();
          return i;
          }
          return null;
          }

          public void addObserver( Observer o ) {
          observers.add( o );
          }

          public void removeObserver( Observer o ) {
          observers.remove( o );
          }

          private void notifyObservers() {
          // loop through and notify each observer
          Iterator i = observers.iterator();
          while( i.hasNext() ) {
          Observer o = ( Observer ) i.next();
          o.update( this );
          }
          }
          }

          IntegerDataBag適用于使用Integer的場合。IntegerDataBag也允許Observer增加和刪除它們自身。

          再看看兩個Observer的實現--IntegerAdder和IntegerPrinter:

          import java.util.Iterator;

          public class IntegerAdder implements Observer {

          private IntegerDataBag bag;

          public IntegerAdder( IntegerDataBag bag ) {
          this.bag = bag;
          bag.addObserver( this );
          }

          public void update( Subject o ) {
          if( o == bag ) {
          System.out.println( "The contents of the IntegerDataBag have changed." );
          int counter = 0;
          Iterator i = bag.iterator();
          while( i.hasNext() ) {
          Integer integer = ( Integer ) i.next();
          counter+=integer.intValue();
          }
          System.out.println( "The new sum of the integers is: " + counter );
          }
          }

          }

          import java.util.Iterator;

          public class IntegerPrinter implements Observer {

          private IntegerDataBag bag;

          public IntegerPrinter( IntegerDataBag bag ) {
          this.bag = bag;
          bag.addObserver( this );
          }

          public void update( Subject o ) {
          if( o == bag ) {
          System.out.println( "The contents of the IntegerDataBag have changed." );
          System.out.println( "The new contents of the IntegerDataBag contains:" );
          Iterator i = bag.iterator();
          while( i.hasNext() ) {
          System.out.println( i.next() );
          }
          }
          }

          }

          IntegerAdder和IntegerPrinter將自己作為觀察者增加到IntegerDataBag。當IntegerAdder接收到一條更新消息時,它先統計bag中的總數,然后顯示結果。同樣,當IntegerPrinter接收到一條更新消息時,它打印出bag中的Interger。

          下面是一個簡單的main(),它使用了上面的幾個類:

          public class Driver {
          public static void main( String [] args ) {
          Integer i1 = new Integer( 1 ); Integer i2 = new Integer( 2 );
          Integer i3 = new Integer( 3 ); Integer i4 = new Integer( 4 );
          Integer i5 = new Integer( 5 ); Integer i6 = new Integer( 6 );
          Integer i7 = new Integer( 7 ); Integer i8 = new Integer( 8 );
          Integer i9 = new Integer( 9 );

          IntegerDataBag bag = new IntegerDataBag();
          bag.add( i1 ); bag.add( i2 ); bag.add( i3 ); bag.add( i4 );
          bag.add( i5 ); bag.add( i6 ); bag.add( i7 ); bag.add( i8 );

          IntegerAdder adder = new IntegerAdder( bag );
          IntegerPrinter printer = new IntegerPrinter( bag );

          // adder and printer add themselves to the bag

          System.out.println( "About to add another integer to the bag:" );
          bag.add( i9 );
          System.out.println("");
          System.out.println("About to remove an integer from the bag:");
          bag.remove( 0 );
          }
          }

          運行main,你將看到:

          c:\javaworld\java Driver
          About to add another integer to the bag:
          The contents of the IntegerDataBag have changed.
          The new sum of the intergers is: 45
          The contents of the IntegerDataBag have changed.
          The new contents of the IntegerDataBag contains:
          1
          2
          3
          4
          5
          6
          7
          8
          9

          About to remove an integer from the bag:
          The contents of the IntegerDataBag have changed.
          The new sum of the intergers is: 44
          The contents of the IntegerDataBag have changed.
          The new contents of the IntegerDataBag contains:
          2
          3
          4
          5
          6
          7
          8
          9

          IntegerDataBag/IntegerAdder/IntegerPrinter是應用Observer模式的一個很簡單的例子。Java本身有大量使用Observer模式的例子:AWT/Swing事件模型,還有java.util.Observer和java.util.Observable接口等,都是很好的例子

          posted on 2006-07-20 10:15 保爾任 閱讀(615) 評論(0)  編輯  收藏 所屬分類: Design Patten

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 广丰县| 射洪县| 淮滨县| 揭西县| 游戏| 武城县| 赣州市| 门头沟区| 临清市| 南部县| 鄂温| 红安县| 富宁县| 永济市| 辛集市| 清河县| 鄂温| 绥德县| 阳江市| 竹山县| 建德市| 涡阳县| 亳州市| 达拉特旗| 姚安县| 中牟县| 斗六市| 英山县| 台东县| 郎溪县| 萨迦县| 抚顺县| 安阳县| 罗甸县| 湟源县| 沧源| 林甸县| 安义县| 余干县| 西华县| 新郑市|