观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,他的所有的依赖者都会收到通知并自动更新;
定义主题,主题的功能是持有观察者的引用,提供注册、取消注册和通知,并且有状态;观察者实现接口中的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);
}
}