前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java行为型模式-观察者模式的使用(一)

java行为型模式-观察者模式的使用(一)

原创
作者头像
IT工作者
发布2022-05-09 18:11:43
4110
发布2022-05-09 18:11:43
举报
文章被收录于专栏:程序技术知识

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

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

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

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

2. 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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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

代码语言:javascript
复制
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对象就会做相应的更新了, 运行结果如下:

代码语言:javascript
复制
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对象发生变化时就可以得到通知,而不要做其他任何改变,非常方便.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档