设计模式——观察者
观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,他的所有的依赖者都会收到通知并自动更新;
定义主题,主题的功能是持有观察者的引用,提供注册、取消注册和通知,并且有状态;观察者实现接口中的update方法,必须注册具体主题;
JDK自带了对观察者的支持功能
被观察者Observable对象,提供add/delete/notifyObserver()和setChanged()设置状态方法
观察者Observer接口,提供update()方法进行相关的更新操作。
观察者类图:
以下程序模拟股票的状态更新功能(使用jdk对观察者支持,参考网上实现)
1.定义Observable 接口实现类,该类是设置股票的信息,并且在数据更新后会通知所有的观察者进行相关状态的更新。
package com.observer; 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(); } }
2.实现观察者Observer实现类,模拟股票的大买家
package com.observer; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Observable; import java.util.Observer; 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(); } }
3.实现观察者Observer实现类,作为第二个观察者
package com.observer; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Observable; import java.util.Observer; 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(); } }
4.测试
package com.observer; 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(); new TradingFool(stockData); new BigBuyer(stockData); 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); } }