Java中观察者模式的使用

  在一对多依赖的对象关系中, 如果这个’一’对象状态发生了变化,那么它所有依赖的’多’对象都应该被通知,然后做相应的变化,这就是观察者模式。 就如同’多’对象一直在观察’一’对象的状态变化一样。

  在观察者模式中最重要的俩个对象分别是:Observable和Observer对象。它们的关系可总结如下:

  1。 Observable和Observer对象是一对多的关系,也就是说一旦Observable对象状态变化,它就要负责通知所有和它有关系的Observer对象,然后做相应的改变。

  1。 Observable对象不会主动去通知各个具体的Observer对象其状态发生了变化,而是提供一个注册接口供Observer对象使用,任何一个Observer对象如果想要被通知,则可以使用这个接口来注册。

  3。 在Observable中有一个集合和一个状态控制开关,所有注册了通知的Observer对象会被保存在这个集合中。这个控制开关就是用来控制Observable是否发生了变化,一旦发生了变化,就通知所有的Observer对象更新状态。

  在java api中分别提供了Observable对象:java.util.Observable和Observer接口:java.util.Observer. 下面用实例来实现一下观察者模式: 股票系统

  所有的类如下:

  StockData (Observable对象,也就是所股票数据发生了变化,它就要通知所有和它有关系的交易实体做相应的变化)

  BigBuyer (Observer对象,实现了Observer接口)

  TradingFool (Observer对象,实现了Observer接口)

  StockQuote 测试类

  在这个例子中一旦StockData对象的状态发生了变化,那BigBuyer和TradingFool都应该受到通知:

  StockData.java:

  Java代码

  importjava.util.Observable; publicclassStockDataextendsObservable { privateStringsymbol; privatefloatclose; privatefloathigh; privatefloatlow; privatelongvolume; publicStockData() {} publicStringgetSymbol() { returnsymbol; } publicfloatgetClose() { returnclose; } publicfloatgetHigh() { returnhigh; } publicfloatgetLow() { returnlow; } publiclonggetVolume() { returnvolume; } publicvoidsendStockData() { setChanged(); notifyObservers(); } publicvoidsetStockData(Stringsymbol,floatclose,floathigh,floatlow,longvolume) { this.symbol=symbol; this.close=close; this.high=high; this.low=low; this.volume=volume; sendStockData(); } }

  BigBuyer.java:

  Java代码

  publicclassBigBuyerimplementsObserver { privateStringsymbol; privatefloatclose; privatefloathigh; privatefloatlow; privatelongvolume; publicBigBuyer(Observableobservable) { observable.addObserver(this);//注册关系 } publicvoidupdate(Observableobservable,Objectargs) { if(observableinstanceofStockData) { StockDatastockData=(StockData)observable; this.symbol=stockData.getSymbol(); this.close=stockData.getClose(); this.high=stockData.getHigh(); this.low=stockData.getLow(); this.volume=stockData.getVolume(); display(); } } publicvoiddisplay() { DecimalFormatSymbolsdfs=newDecimalFormatSymbols(); DecimalFormatvolumeFormat=newDecimalFormat(“###,###,###,###”,dfs); DecimalFormatpriceFormat=newDecimalFormat(“###.00”,dfs); System.out.println(“BigBuyerreports…”); System.out.println(“\tThelasteststockquotefor”+symbol+”is:”); System.out.println(“\t$”+priceFormat.format(close)+”pershare(close).”); System.out.println(“\t$”+priceFormat.format(high)+”pershare(high).”); System.out.println(“\t$”+priceFormat.format(low)+”pershare(low).”); System.out.println(“\t”+volumeFormat.format(volume)+”sharestraded.”); System.out.println(); } }

  TradingFool.java:

  Java代码

  publicclassTradingFoolimplementsObserver { privateStringsymbol; privatefloatclose; publicTradingFool(Observableobservable) { observable.addObserver(this);//注册关系 } publicvoidupdate(Observableobservable,Objectargs) { if(observableinstanceofStockData) { StockDatastockData=(StockData)observable; this.symbol=stockData.getSymbol(); this.close=stockData.getClose(); display(); } } publicvoiddisplay() { DecimalFormatSymbolsdfs=newDecimalFormatSymbols(); DecimalFormatpriceFormat=newDecimalFormat(“###.00”,dfs); System.out.println(“TradingFoolsays…”); System.out.println(“\t”+symbol+”iscurrentlytradingat$”+priceFormat.format(close)+”pershare.”); System.out.println(); } }

  StokeQuote.java

  Java代码

  publicclassStockQuotes { publicstaticvoidmain(String[]args) { System.out.println(); System.out.println(“–StockQuoteApplication–“); System.out.println(); StockDatastockData=newStockData(); //registerobservers… newTradingFool(stockData); newBigBuyer(stockData); //generatechangestostockdata… stockData.setStockData(“JUPM”,16.10f,16.15f,15.34f,(long)481172); stockData.setStockData(“SUNW”,4.84f,4.90f,4.79f,(long)68870233); stockData.setStockData(“MSFT”,23.17f,23.37f,23.05f,(long)75091400); } }

  在测试类中我们可以看到俩个Observer对象都注册了Observable对象,而当Observable对象发生改变时,这俩个Observable对象就会做相应的更新了,运行结果如下:

  Java代码

  BigBuyerreports… ThelasteststockquoteforJUPMis: $16.10pershare(close). $16.15pershare(high). $15.34pershare(low). 481,172sharestraded. TradingFoolsays… JUPMiscurrentlytradingat$16.10pershare. BigBuyerreports… ThelasteststockquoteforSUNWis: $4.84pershare(close). $4.90pershare(high). $4.79pershare(low). 68,870,233sharestraded. TradingFoolsays… SUNWiscurrentlytradingat$4.84pershare. BigBuyerreports… ThelasteststockquoteforMSFTis: $23.17pershare(close). $23.37pershare(high). $23.05pershare(low). 75,091,400sharestraded. TradingFoolsays… MSFTiscurrentlytradingat$23.17pershare.

  我们通过Observable源码可以看到,其实Observable对象不关心具体的Observer的实例类型。 只要是实现了Observer接口的Observer对象都可以得到通知,这就为我们如果想要对模型进行扩展提供了方便,使Observable对象和Observer对象实现了松耦合。 如果我们需要添加一个新的Observer对象时,我们只要注册一下,当Observable对象发生变化时就可以得到通知,而不要做其他任何改变,非常方便。

尝到你和你在一起的快乐,你是唯一能让我尝到酸甜苦辣的人。

Java中观察者模式的使用

相关文章:

你感兴趣的文章:

标签云: