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代码

 
  1. importjava.util.Observable;
  2. publicclassStockDataextendsObservable
  3. {
  4. privateStringsymbol;
  5. privatefloatclose;
  6. privatefloathigh;
  7. privatefloatlow;
  8. privatelongvolume;
  9. publicStockData()
  10. {}
  11. publicStringgetSymbol()
  12. {
  13. returnsymbol;
  14. }
  15. publicfloatgetClose()
  16. {
  17. returnclose;
  18. }
  19. publicfloatgetHigh()
  20. {
  21. returnhigh;
  22. }
  23. publicfloatgetLow()
  24. {
  25. returnlow;
  26. }
  27. publiclonggetVolume()
  28. {
  29. returnvolume;
  30. }
  31. publicvoidsendStockData()
  32. {
  33. setChanged();
  34. notifyObservers();
  35. }
  36. publicvoidsetStockData(Stringsymbol,floatclose,floathigh,floatlow,longvolume)
  37. {
  38. this.symbol=symbol;
  39. this.close=close;
  40. this.high=high;
  41. this.low=low;
  42. this.volume=volume;
  43. sendStockData();
  44. }
  45. }

BigBuyer.java:

Java代码

 
  1. publicclassBigBuyerimplementsObserver
  2. {
  3. privateStringsymbol;
  4. privatefloatclose;
  5. privatefloathigh;
  6. privatefloatlow;
  7. privatelongvolume;
  8. publicBigBuyer(Observableobservable)
  9. {
  10. observable.addObserver(this);//注册关系
  11. }
  12. publicvoidupdate(Observableobservable,Objectargs)
  13. {
  14. if(observableinstanceofStockData)
  15. {
  16. StockDatastockData=(StockData)observable;
  17. this.symbol=stockData.getSymbol();
  18. this.close=stockData.getClose();
  19. this.high=stockData.getHigh();
  20. this.low=stockData.getLow();
  21. this.volume=stockData.getVolume();
  22. display();
  23. }
  24. }
  25. publicvoiddisplay()
  26. {
  27. DecimalFormatSymbolsdfs=newDecimalFormatSymbols();
  28. DecimalFormatvolumeFormat=newDecimalFormat("###,###,###,###",dfs);
  29. DecimalFormatpriceFormat=newDecimalFormat("###.00",dfs);
  30. System.out.println("BigBuyerreports...");
  31. System.out.println("\tThelasteststockquotefor"+symbol+"is:");
  32. System.out.println("\t$"+priceFormat.format(close)+"pershare(close).");
  33. System.out.println("\t$"+priceFormat.format(high)+"pershare(high).");
  34. System.out.println("\t$"+priceFormat.format(low)+"pershare(low).");
  35. System.out.println("\t"+volumeFormat.format(volume)+"sharestraded.");
  36. System.out.println();
  37. }
  38. }

TradingFool.java:

Java代码

 
  1. publicclassTradingFoolimplementsObserver
  2. {
  3. privateStringsymbol;
  4. privatefloatclose;
  5. publicTradingFool(Observableobservable)
  6. {
  7. observable.addObserver(this);//注册关系
  8. }
  9. publicvoidupdate(Observableobservable,Objectargs)
  10. {
  11. if(observableinstanceofStockData)
  12. {
  13. StockDatastockData=(StockData)observable;
  14. this.symbol=stockData.getSymbol();
  15. this.close=stockData.getClose();
  16. display();
  17. }
  18. }
  19. publicvoiddisplay()
  20. {
  21. DecimalFormatSymbolsdfs=newDecimalFormatSymbols();
  22. DecimalFormatpriceFormat=newDecimalFormat("###.00",dfs);
  23. System.out.println("TradingFoolsays...");
  24. System.out.println("\t"+symbol+"iscurrentlytradingat$"+priceFormat.format(close)+"pershare.");
  25. System.out.println();
  26. }
  27. }

StokeQuote.java

Java代码

 
  1. publicclassStockQuotes
  2. {
  3. publicstaticvoidmain(String[]args)
  4. {
  5. System.out.println();
  6. System.out.println("--StockQuoteApplication--");
  7. System.out.println();
  8. StockDatastockData=newStockData();
  9. //registerobservers...
  10. newTradingFool(stockData);
  11. newBigBuyer(stockData);
  12. //generatechangestostockdata...
  13. stockData.setStockData("JUPM",16.10f,16.15f,15.34f,(long)481172);
  14. stockData.setStockData("SUNW",4.84f,4.90f,4.79f,(long)68870233);
  15. stockData.setStockData("MSFT",23.17f,23.37f,23.05f,(long)75091400);
  16. }
  17. }

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

Java代码

 
  1. BigBuyerreports...
  2. ThelasteststockquoteforJUPMis:
  3. $16.10pershare(close).
  4. $16.15pershare(high).
  5. $15.34pershare(low).
  6. 481,172sharestraded.
  7. TradingFoolsays...
  8. JUPMiscurrentlytradingat$16.10pershare.
  9. BigBuyerreports...
  10. ThelasteststockquoteforSUNWis:
  11. $4.84pershare(close).
  12. $4.90pershare(high).
  13. $4.79pershare(low).
  14. 68,870,233sharestraded.
  15. TradingFoolsays...
  16. SUNWiscurrentlytradingat$4.84pershare.
  17. BigBuyerreports...
  18. ThelasteststockquoteforMSFTis:
  19. $23.17pershare(close).
  20. $23.37pershare(high).
  21. $23.05pershare(low).
  22. 75,091,400sharestraded.
  23. TradingFoolsays...
  24. MSFTiscurrentlytradingat$23.17pershare.

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值