Observer (观察者)模式
GoF : Observer 模式的意图是“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象 都得到通知并被自动更新”。
举个例子:一般在炒股票的时候人们总是紧盯着大盘的起伏涨跌。根据某支股票的涨跌来决定买进或抛出。 而在整个交易中紧盯着大盘的这个人就是一个观察着。他将观察的结果通知他的亲属朋友,或自己做出决定去交易。 Observer 模式是如此的有用,以至于在 Java 的 JDK 包当中容纳了 Observer 模式的一个实现版本。 Observable 类和 Observer 接口组成了这个模 式。关于 Observable 类和 Observer 接口在 JDK 的帮助文档中有详细的介绍。在 Observer 模式的学习过程中,我运用了 JDK 中的 Observable 类和 Observer 接口来实现了 Observer 模式的代码。
下面是 Observer 模式的 UML 图:
上图我画的不是很规范,但是已经表达出了 Observer 模式。
下面是实例代码:
package Observer;
import java.util.Observable;
public class Stock extends Observable // 继承 Observable 类
{
private String stockName;
private float stockPrice;
private int stockId;
public Stock(int id, String name, float price)// 设定初始状态
{
this.stockId = id;
this.stockName = name;
this.stockPrice = price;
}//end Stock(...)
public String getName()
{
return stockName;
}//end getName()
public float getPrice()
{
return stockPrice;
}//end getPrice()
public int getId()
{
return this.stockId;
}//end getId()
public void setName(String name)
{
this.stockName = name;
setChanged(); // 名称已经改变
notifyObservers("stockName"); //
}//end setName(...)
public void setPrice(float price)
{
this.stockPrice = price;
setChanged();
notifyObservers("stockPrice");
}//end setPrice(...)
}//end class Stock
package Observer;
import java.util.Observable;
import java.util.Observer;
public class NameObserver implements Observer
{
public void update(Observable obj, Object arg)
{
try{
if(arg instanceof String){
// System.out.println("arg333 = " + arg);
String argName = (String)arg;
// System.out.println("argName = " + argName);
if(argName.trim().equalsIgnoreCase("stockName")){
// System.out.println("name here");
int id = 0;
String name = "";
if(obj instanceof Stock){
Stock sto = (Stock)obj;
name = sto.getName();
id = sto.getId();
}
System.out.println("NameObserver: Stock " + id + "'s name has changed to " + name);
}
}
}catch(Exception e){
e.printStackTrace();
}
}//end update(...)
}//end class NameObserver
package Observer;
import java.util.Observable;
import java.util.Observer;
public class PriceObserver implements Observer
{
public void update(Observable obj, Object arg)
{
try{
if(arg instanceof String){
String argName = (String)arg;
if(argName.trim().equalsIgnoreCase("stockPrice")){
int id = 0;
float price = 0.0f;
if(obj instanceof Stock){
Stock sto = (Stock)obj;
price = sto.getPrice();
id = sto.getId();
}
System.out.println("PriceObserver: Stock " + id + "'s price has changed to " + price);
}
}
}catch(Exception e){
e.printStackTrace();
}
}//end update(...)
}//end class PriceObserver
测试代码:
package Observer;
public class ObserverPattern
{
private Stock stock;// 实例化一个股票对象
private NameObserver stockName; // 实 例化一个观察股票名称的对象
private PriceObserver stockPrice;// 实 例化一个观察股票价格的对象
public ObserverPattern()// 初始化类成员
{
stock = new Stock(1, " 海南椰岛 ", 2.92f);// 初始一支股票的名称和价格
stockName = new NameObserver();
stockPrice = new PriceObserver();
}//end ObserverPattern()
public void showHowToObserver()
{
stock.addObserver(stockName);
stock.addObserver(stockPrice);
// stock.setName("/" 百度 /"");// 重新设置股票的名称
stock.setPrice(123.98f);// 重新设置股票的价格
// System.out.println("");
// stock.setName("/"Google/"");// 再次设置股票的名称
stock.setPrice(234.87f);// 再次设置股票的价格
}//end showHowToObserver()
public static void main(String[] args)
{
System.out.println("The observer pattern!");
ObserverPattern op = new ObserverPattern();
op.showHowToObserver();
}//end main(...)
}//end class ObserverPattern
Observer 模式充分体现了 OO 的特 性,理解了 Observer 模式能更好的理解 OO 思 想。