行为型模式-观察者模式的使用

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

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

    在观察者模式中最重要的俩个对象分别是: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. import java.util.Observable;     
    2.     
    3. public class StockData extends Observable     
    4.     {     
    5.     private String symbol;     
    6.     private float close;     
    7.     private float high;     
    8.     private float low;     
    9.     private long volume;     
    10.     
    11.     public StockData()     
    12.         {}     
    13.     
    14.     public String getSymbol()     
    15.         {     
    16.         return symbol;     
    17.         }     
    18.     
    19.     public float getClose()     
    20.         {     
    21.         return close;     
    22.         }     
    23.     
    24.     public float getHigh()     
    25.         {     
    26.         return high;     
    27.         }     
    28.     
    29.     public float getLow()     
    30.         {     
    31.         return low;     
    32.         }     
    33.     
    34.     public long getVolume()     
    35.         {     
    36.         return volume;     
    37.         }     
    38.     
    39.     public void sendStockData()     
    40.         {     
    41.         setChanged();     
    42.         notifyObservers();     
    43.         }     
    44.     
    45.     public void setStockData(String symbol,float close,float high,float low,long volume)     
    46.         {     
    47.         this.symbol = symbol;     
    48.         this.close = close;     
    49.         this.high = high;     
    50.         this.low = low;     
    51.         this.volume = volume;     
    52.         sendStockData();     
    53.         }     
    54.     }    

    BigBuyer.java:

    Java代码

         
         
    1. public class BigBuyer implements Observer     
    2.     {     
    3.     private String symbol;     
    4.     private float close;     
    5.     private float high;     
    6.     private float low;     
    7.     private long volume;     
    8.     
    9.     public BigBuyer(Observable observable)     
    10.         {     
    11.         observable.addObserver(this); //注册关系     
    12.         }     
    13.     
    14.     public void update(Observable observable,Object args)     
    15.         {     
    16.         if(observable instanceof StockData)     
    17.             {     
    18.             StockData stockData = (StockData)observable;     
    19.             this.symbol = stockData.getSymbol();     
    20.             this.close = stockData.getClose();     
    21.             this.high = stockData.getHigh();     
    22.             this.low = stockData.getLow();     
    23.             this.volume = stockData.getVolume();     
    24.             display();     
    25.             }     
    26.         }     
    27.     
    28.     public void display()     
    29.         {     
    30.         DecimalFormatSymbols dfs = new DecimalFormatSymbols();     
    31.         DecimalFormat volumeFormat = new DecimalFormat("###,###,###,###",dfs);     
    32.         DecimalFormat priceFormat = new DecimalFormat("###.00",dfs);     
    33.         System.out.println("Big Buyer reports... ");     
    34.         System.out.println("\tThe lastest stock quote for " + symbol + " is:");     
    35.         System.out.println("\t$" + priceFormat.format(close) + " per share (close).");     
    36.         System.out.println("\t$" + priceFormat.format(high) + " per share (high).");     
    37.         System.out.println("\t$" + priceFormat.format(low) + " per share (low).");     
    38.         System.out.println("\t" + volumeFormat.format(volume) + " shares traded.");     
    39.         System.out.println();     
    40.         }     
    41.     }    

    TradingFool.java:

    Java代码

         
         
    1. public class TradingFool implements Observer     
    2.     {     
    3.     private String symbol;     
    4.     private float close;     
    5.     
    6.     public TradingFool(Observable observable)     
    7.         {     
    8.         observable.addObserver(this);//注册关系     
    9.         }     
    10.     
    11.     public void update(Observable observable,Object args)     
    12.         {     
    13.         if(observable instanceof StockData)     
    14.             {     
    15.             StockData stockData = (StockData)observable;     
    16.             this.symbol = stockData.getSymbol();     
    17.             this.close = stockData.getClose();     
    18.             display();     
    19.             }     
    20.         }     
    21.     
    22.     public void display()     
    23.         {     
    24.         DecimalFormatSymbols dfs = new DecimalFormatSymbols();     
    25.         DecimalFormat priceFormat = new DecimalFormat("###.00",dfs);     
    26.         System.out.println("Trading Fool says... ");     
    27.         System.out.println("\t" + symbol + " is currently trading at $" + priceFormat.format(close) + " per share.");     
    28.         System.out.println();     
    29.         }     
    30.     }    

    StokeQuote.java

    Java代码

         
         
    1. public class StockQuotes     
    2.     {     
    3.     public static void main(String[] args)     
    4.         {     
    5.         System.out.println();     
    6.         System.out.println("-- Stock Quote Application --");     
    7.         System.out.println();     
    8.     
    9.         StockData stockData = new StockData();     
    10.     
    11.         // register observers...     
    12.         new TradingFool(stockData);     
    13.         new BigBuyer(stockData);     
    14.     
    15.         // generate changes to stock data...     
    16.         stockData.setStockData("JUPM",16.10f,16.15f,15.34f,(long)481172);     
    17.         stockData.setStockData("SUNW",4.84f,4.90f,4.79f,(long)68870233);     
    18.         stockData.setStockData("MSFT",23.17f,23.37f,23.05f,(long)75091400);     
    19.         }     
    20.     }   

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

    Java代码

         
         
    1. Big Buyer reports...      
    2.     The lastest stock quote for JUPM is:     
    3.     $16.10 per share (close).     
    4.     $16.15 per share (high).     
    5.     $15.34 per share (low).     
    6.     481,172 shares traded.     
    7.     
    8. Trading Fool says...      
    9.     JUPM is currently trading at $16.10 per share.     
    10.     
    11. Big Buyer reports...      
    12.     The lastest stock quote for SUNW is:     
    13.     $4.84 per share (close).     
    14.     $4.90 per share (high).     
    15.     $4.79 per share (low).     
    16.     68,870,233 shares traded.     
    17.     
    18. Trading Fool says...      
    19.     SUNW is currently trading at $4.84 per share.     
    20.     
    21. Big Buyer reports...      
    22.     The lastest stock quote for MSFT is:     
    23.     $23.17 per share (close).     
    24.     $23.37 per share (high).     
    25.     $23.05 per share (low).     
    26.     75,091,400 shares traded.     
    27.     
    28. Trading Fool says...      
    29.     MSFT is currently trading at $23.17 per share.    

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


    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值