java 觀察者模式

  在一對多依賴的對象關係中, 若是這個'一'對象狀態發生了變化,那麼它全部依賴的'多'對象都應該被通知,而後作相應的變化,這就是觀察者模式.  就如同'多'對象一直在觀察'一'對象的狀態變化同樣.java

      在觀察者模式中最重要的倆個對象分別是:Observable和Observer對象.它們的關係可總結以下:api

1. Observable和Observer對象是一對多的關係,也就是說一旦Observable對象狀態變化,它就要負責通知全部和它有關係的Observer對象,而後作相應的改變.測試

2. Observable對象不會主動去通知各個具體的Observer對象其狀態發生了變化,而是提供一個註冊接口供Observer對象使用,任何一個Observer對象若是想要被通知,則能夠使用這個接口來註冊.this

3. 在Observable中有一個集合和一個狀態控制開關,全部註冊了通知的Observer對象會被保存在這個集合中.這個控制開關就是用來控制Observable是否發生了變化,一旦發生了變化,就通知全部的Observer對象更新狀態.spa

 

在java  api中分別提供了Observable對象:java.util.Observable和Observer接口:java.util.Observer. 下面用實例來實現一下觀察者模式: 股票系統orm

全部的類以下:server

 

StockData     (Observable對象,也就是所股票數據發生了變化,它就要通知全部和它有關係的交易實體作相應的變化)對象

BigBuyer       (Observer對象, 實現了Observer接口)接口

TradingFool   (Observer對象, 實現了Observer接口)ci

StockQuote   測試類

在這個例子中一旦StockData對象的狀態發生了變化,那BigBuyer和TradingFool都應該受到通知:

 

StockData.java:

 

Java代碼  

import java.util.Observable;  

  

public class StockData extends Observable  

    {  

    private String symbol;  

    private float close;  

    private float high;  

    private float low;  

    private long volume;  

  

    public StockData()  

        {}  

  

    public String getSymbol()  

        {  

        return symbol;  

        }  

  

    public float getClose()  

        {  

        return close;  

        }  

  

    public float getHigh()  

        {  

        return high;  

        }  

  

    public float getLow()  

        {  

        return low;  

        }  

  

    public long getVolume()  

        {  

        return volume;  

        }  

  

    public void sendStockData()  

        {  

        setChanged();  

        notifyObservers();  

        }  

  

    public void setStockData(String symbol,float close,float high,float low,long volume)  

        {  

        this.symbol = symbol;  

        this.close = close;  

        this.high = high;  

        this.low = low;  

        this.volume = volume;  

        sendStockData();  

        }  

    }  

 

BigBuyer.java:

Java代碼  

public class BigBuyer implements Observer  

    {  

    private String symbol;  

    private float close;  

    private float high;  

    private float low;  

    private long volume;  

  

    public BigBuyer(Observable observable)  

        {  

        observable.addObserver(this); //註冊關係  

        }  

  

    public void update(Observable observable,Object args)  

        {  

        if(observable instanceof StockData)  

            {  

            StockData stockData = (StockData)observable;  

            this.symbol = stockData.getSymbol();  

            this.close = stockData.getClose();  

            this.high = stockData.getHigh();  

            this.low = stockData.getLow();  

            this.volume = stockData.getVolume();  

            display();  

            }  

        }  

  

    public void display()  

        {  

        DecimalFormatSymbols dfs = new DecimalFormatSymbols();  

        DecimalFormat volumeFormat = new DecimalFormat("###,###,###,###",dfs);  

        DecimalFormat priceFormat = new DecimalFormat("###.00",dfs);  

        System.out.println("Big Buyer reports... ");  

        System.out.println("\tThe lastest stock quote for " + symbol + " is:");  

        System.out.println("\t$" + priceFormat.format(close) + " per share (close).");  

        System.out.println("\t$" + priceFormat.format(high) + " per share (high).");  

        System.out.println("\t$" + priceFormat.format(low) + " per share (low).");  

        System.out.println("\t" + volumeFormat.format(volume) + " shares traded.");  

        System.out.println();  

        }  

    }  

 

 TradingFool.java:

Java代碼  

public class TradingFool implements Observer  

    {  

    private String symbol;  

    private float close;  

  

    public TradingFool(Observable observable)  

        {  

        observable.addObserver(this);//註冊關係  

        }  

  

    public void update(Observable observable,Object args)  

        {  

        if(observable instanceof StockData)  

            {  

            StockData stockData = (StockData)observable;  

            this.symbol = stockData.getSymbol();  

            this.close = stockData.getClose();  

            display();  

            }  

        }  

  

    public void display()  

        {  

        DecimalFormatSymbols dfs = new DecimalFormatSymbols();  

        DecimalFormat priceFormat = new DecimalFormat("###.00",dfs);  

        System.out.println("Trading Fool says... ");  

        System.out.println("\t" + symbol + " is currently trading at $" + priceFormat.format(close) + " per share.");  

        System.out.println();  

        }  

    }  

 

StokeQuote.java

Java代碼  

public class StockQuotes  

    {  

    public static void main(String[] args)  

        {  

        System.out.println();  

        System.out.println("-- Stock Quote Application --");  

        System.out.println();  

  

        StockData stockData = new StockData();  

  

        // register observers...  

        new TradingFool(stockData);  

        new BigBuyer(stockData);  

  

        // generate changes to stock data...  

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

Big Buyer reports...   

    The lastest stock quote for JUPM is:  

    $16.10 per share (close).  

    $16.15 per share (high).  

    $15.34 per share (low).  

    481,172 shares traded.  

  

Trading Fool says...   

    JUPM is currently trading at $16.10 per share.  

  

Big Buyer reports...   

    The lastest stock quote for SUNW is:  

    $4.84 per share (close).  

    $4.90 per share (high).  

    $4.79 per share (low).  

    68,870,233 shares traded.  

  

Trading Fool says...   

    SUNW is currently trading at $4.84 per share.  

  

Big Buyer reports...   

    The lastest stock quote for MSFT is:  

    $23.17 per share (close).  

    $23.37 per share (high).  

    $23.05 per share (low).  

    75,091,400 shares traded.  

  

Trading Fool says...   

    MSFT is currently trading at $23.17 per share.  

咱們經過Observable源碼能夠看到,其實Observable對象不關心具體的Observer的實例類型. 只要是實現了Observer接口的Observer對象均可以獲得通知,這就爲咱們若是想要對模型進行擴展提供了方便,使Observable對象和 Observer對象實現了鬆耦合. 若是咱們須要添加一個新的Observer對象時,咱們只要註冊一下,當Observable對象發生變化時就能夠獲得通知,而不要作其餘任何改變,很是 方便.

相關文章
相關標籤/搜索