免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
使用Observer模式
 

Java Q&A: 使用Observer模式

A:我想在自己的Java程序中使用Observer模式?;诖耍芊裉峁┠承┦纠a來(lái)演示如何去做?

Q:正如面向?qū)ο缶幊逃兄诖a復(fù)用一樣,設(shè)計(jì)模式可以促進(jìn)設(shè)計(jì)復(fù)用。確實(shí),設(shè)計(jì)模式可以讓你復(fù)用那些正確的、成熟的設(shè)計(jì)。但近來(lái),批評(píng)設(shè)計(jì)模式的聲音越來(lái)越多。批評(píng)者指出,缺乏經(jīng)驗(yàn)的開(kāi)發(fā)者會(huì)很容易地掉進(jìn) "模式陷阱" 之中。

模式陷阱讓缺乏經(jīng)驗(yàn)的開(kāi)發(fā)者迷失了方向。因而,他們?cè)谔幚韱?wèn)題時(shí)不是去尋找可能存在的最好方案,而把最終目標(biāo)集中在盡可能地實(shí)現(xiàn)更多的設(shè)計(jì)模式之上。在一些人看來(lái),使用設(shè)計(jì)模式好象必然會(huì)帶來(lái)良好的設(shè)計(jì)。按照這個(gè)邏輯,只要大量使用設(shè)計(jì)模式,就必然為你產(chǎn)生一個(gè)優(yōu)秀的設(shè)計(jì)!然而現(xiàn)實(shí)中,這一觀(guān)點(diǎn)卻導(dǎo)致出許多毫無(wú)意義的設(shè)計(jì)--即使這個(gè)設(shè)計(jì)采用了多個(gè)設(shè)計(jì)模式??磥?lái)很遺憾,設(shè)計(jì)模式并不能保證良好的設(shè)計(jì)。

要想在設(shè)計(jì)中正確地運(yùn)用一個(gè)設(shè)計(jì)模式,必須確保三個(gè)條件:

1. 弄清你的問(wèn)題

2. 了解這個(gè)模式

3. 理解這個(gè)模式如何解決你的問(wèn)題

首先,最重要的是條件1。如果不能完全地弄清你要解決的問(wèn)題,何談運(yùn)用模式?

還要知道條件2:必須完全了解你想運(yùn)用的模式。不了解它怎么能運(yùn)用它?更重要的是,連一個(gè)模式做什么都不知道,又如何想到去用它?

最后一點(diǎn),如果你不能清楚地說(shuō)出模式將怎樣解決你的問(wèn)題(為什么這個(gè)模式合適),那還是放棄它。僅僅為了用模式本身而去用它,就會(huì)掉進(jìn)模式陷阱之中。

我并不是在說(shuō)提這個(gè)問(wèn)題的讀者也一定會(huì)掉進(jìn)模式陷阱。但從提問(wèn)的表達(dá)上來(lái)看,它很容易誤導(dǎo)一些開(kāi)發(fā)者去理解設(shè)計(jì)模式。我對(duì)這個(gè)提問(wèn)的理解是,這位讀者應(yīng)該清楚自己需要解決的問(wèn)題,也了解Observer模式,他/她只是不知道如何用Java來(lái)實(shí)現(xiàn)。

在給出一個(gè)Java示例之前,為了有助于其他讀者也能理解,先簡(jiǎn)要介紹一下Observer模式。

簡(jiǎn)單來(lái)說(shuō),Observer模式讓一個(gè)對(duì)象(觀(guān)察者,Observer)去監(jiān)視另一個(gè)對(duì)象(目標(biāo),Subject);它使得目標(biāo)和觀(guān)察者之間建立一種 "發(fā)布--訂閱"(publish-subscribe )的關(guān)系。通過(guò)Observer模式,觀(guān)察者可以向目標(biāo)登記,表明自己要從目標(biāo)接收事件。目標(biāo)需要向觀(guān)察者通知事件時(shí),只是簡(jiǎn)單地將事件發(fā)給每一個(gè)觀(guān)察者。

例如,有一個(gè)基于某種數(shù)據(jù)模型的電子表格。只要數(shù)據(jù)模型發(fā)生變化,電子表格就需要更新表格單元以及內(nèi)嵌的圖表。這個(gè)例子中,目標(biāo)是數(shù)據(jù)模型,觀(guān)察者是表格單元和圖表。當(dāng)觀(guān)察者接收到數(shù)據(jù)模型已經(jīng)變化的通知時(shí),它們就更新自己。

Observer模式的好處是:它解除了觀(guān)察者和目標(biāo)之間的耦合關(guān)系。目標(biāo)不需要知道它的觀(guān)察者的任何信息。相反,目標(biāo)只是允許觀(guān)察者訂閱事件。當(dāng)目標(biāo)產(chǎn)生一個(gè)事件時(shí),它簡(jiǎn)單地將事件傳給每一個(gè)觀(guān)察者。

看看下面的Java示例:

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

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

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

Observer接口(如上)列出了一個(gè)方法(method),每個(gè)Observer都必須實(shí)現(xiàn)它,以使Subject可以發(fā)送更新消息給Observer。

下面看看Subject的一個(gè)簡(jiǎn)單的實(shí)現(xiàn)--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的場(chǎng)合。IntegerDataBag也允許Observer增加和刪除它們自身。

再看看兩個(gè)Observer的實(shí)現(xiàn)--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將自己作為觀(guān)察者增加到IntegerDataBag。當(dāng)IntegerAdder接收到一條更新消息時(shí),它先統(tǒng)計(jì)bag中的總數(shù),然后顯示結(jié)果。同樣,當(dāng)IntegerPrinter接收到一條更新消息時(shí),它打印出bag中的Interger。

下面是一個(gè)簡(jiǎn)單的main(),它使用了上面的幾個(gè)類(lèi):

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

運(yùn)行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是應(yīng)用Observer模式的一個(gè)很簡(jiǎn)單的例子。Java本身有大量使用Observer模式的例子:AWT/Swing事件模型,還有java.util.Observer和java.util.Observable接口等,都是很好的例子。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
RxJava基本使用
java設(shè)計(jì)模式———觀(guān)察者模式
觀(guān)察者模式
Java帝國(guó)之觀(guān)察者模式
18. 觀(guān)察者模式
java設(shè)計(jì)模式精講 Debug 方式+內(nèi)存分析 第21章 觀(guān)察者模式講解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服