观察者模式(Observer Pattern)的意图是在多个对象之间定义一对多的依赖关系,当一个对象的状态改变时,会通知依赖于他的对象,并根据状态做出想用的反应。
观察者模式(Observer Pattern)涉及的角色有:
- 抽象主题(Abstract Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色
- 具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
- 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
-
具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
观察者在java.util中提供了观察者模式的支持。
现在对商品的价格和库存做一个监控,当商品的价格和库存的小于阀值时向用户发送提醒消息。
- /**
- *
- * @author zhangwei_david
- * @version $Id: MonitorState.java, v 0.1 2014年11月24日 下午3:18:09 zhangwei_david Exp $
- */
- public class Product extends Observable {
- private final int id = 102;
- private double price = 100.00;
- private int stock = 100;
- /**
- * Getter method for property <tt>price</tt>.
- *
- * @return property value of price
- */
- public double getPrice() {
- return price;
- }
- /**
- * Getter method for property <tt>stock</tt>.
- *
- * @return property value of stock
- */
- public int getStock() {
- return stock;
- }
- /**
- * Setter method for property <tt>price</tt>.
- *
- * @param price value to be assigned to property price
- */
- public void setPrice(double price) {
- this.price = price;
- sendNotify(price);
- }
- /**
- * Setter method for property <tt>stock</tt>.
- *
- * @param stock value to be assigned to property stock
- */
- public void setStock(int stock) {
- this.stock = stock;
- sendNotify(stock);
- }
- /**
- * Getter method for property <tt>id</tt>.
- *
- * @return property value of id
- */
- public int getId() {
- return id;
- }
- /**
- * 发送通知
- */
- private void sendNotify(Object obj) {
- setChanged();
- notifyObservers(obj);
- }
- }
/**
*
* @author zhangwei_david
* @version $Id: MonitorState.java, v 0.1 2014年11月24日 下午3:18:09 zhangwei_david Exp $
*/
public class Product extends Observable {
private final int id = 102;
private double price = 100.00;
private int stock = 100;
/**
* Getter method for property <tt>price</tt>.
*
* @return property value of price
*/
public double getPrice() {
return price;
}
/**
* Getter method for property <tt>stock</tt>.
*
* @return property value of stock
*/
public int getStock() {
return stock;
}
/**
* Setter method for property <tt>price</tt>.
*
* @param price value to be assigned to property price
*/
public void setPrice(double price) {
this.price = price;
sendNotify(price);
}
/**
* Setter method for property <tt>stock</tt>.
*
* @param stock value to be assigned to property stock
*/
public void setStock(int stock) {
this.stock = stock;
sendNotify(stock);
}
/**
* Getter method for property <tt>id</tt>.
*
* @return property value of id
*/
public int getId() {
return id;
}
/**
* 发送通知
*/
private void sendNotify(Object obj) {
setChanged();
notifyObservers(obj);
}
}
- /**
- *商品库存的观察者
- * @author zhangwei_david
- * @version $Id: DelayMonitor.java, v 0.1 2014年11月24日 下午3:31:41 zhangwei_david Exp $
- */
- public class PriceObserver implements Observer {
- /**
- * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
- */
- public void update(Observable observable, Object arg) {
- if (observable instanceof Product && arg instanceof Double) {
- Product product = (Product) observable;
- System.out.println("您 购物车中的商品价格有新的变化 当前价格是 " + product.getPrice() + " 元");
- }
- }
- /**
- *
- * @param monitorState
- */
- public void register(Observable observable) {
- observable.addObserver(this);
- }
- }
/**
*商品库存的观察者
* @author zhangwei_david
* @version $Id: DelayMonitor.java, v 0.1 2014年11月24日 下午3:31:41 zhangwei_david Exp $
*/
public class PriceObserver implements Observer {
/**
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
public void update(Observable observable, Object arg) {
if (observable instanceof Product && arg instanceof Double) {
Product product = (Product) observable;
System.out.println("您 购物车中的商品价格有新的变化 当前价格是 " + product.getPrice() + " 元");
}
}
/**
*
* @param monitorState
*/
public void register(Observable observable) {
observable.addObserver(this);
}
}
- /**
- *商品库存的观察者
- * @author zhangwei_david
- * @version $Id: DelayMonitor.java, v 0.1 2014年11月24日 下午3:31:41 zhangwei_david Exp $
- */
- public class StockObserver implements Observer {
- /**
- * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
- */
- public void update(Observable observable, Object arg) {
- if (observable instanceof Product && arg instanceof Integer) {
- Product product = (Product) observable;
- if (product.getStock() < 5) {
- System.out.println("您 购物车中的商品 库存紧张,剩余 " + product.getStock() + " 件");
- }
- }
- }
- /**
- *
- * @param monitorState
- */
- public void register(Observable observable) {
- observable.addObserver(this);
- }
- }
/**
*商品库存的观察者
* @author zhangwei_david
* @version $Id: DelayMonitor.java, v 0.1 2014年11月24日 下午3:31:41 zhangwei_david Exp $
*/
public class StockObserver implements Observer {
/**
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
public void update(Observable observable, Object arg) {
if (observable instanceof Product && arg instanceof Integer) {
Product product = (Product) observable;
if (product.getStock() < 5) {
System.out.println("您 购物车中的商品 库存紧张,剩余 " + product.getStock() + " 件");
}
}
}
/**
*
* @param monitorState
*/
public void register(Observable observable) {
observable.addObserver(this);
}
}
- /**
- *
- * @author zhangwei_david
- * @version $Id: Client.java, v 0.1 2014年11月24日 下午3:26:58 zhangwei_david Exp $
- */
- public class Client {
- /**
- *
- * @param args
- */
- public static void main(String[] args) {
- Product monitorState = new Product();
- new StockObserver().register(monitorState);
- monitorState.setPrice(100);
- monitorState.setStock(1);
- new PriceObserver().register(monitorState);
- monitorState.setPrice(99);
- monitorState.setPrice(98);
- monitorState.setPrice(97);
- }
- }
/**
*
* @author zhangwei_david
* @version $Id: Client.java, v 0.1 2014年11月24日 下午3:26:58 zhangwei_david Exp $
*/
public class Client {
/**
*
* @param args
*/
public static void main(String[] args) {
Product monitorState = new Product();
new StockObserver().register(monitorState);
monitorState.setPrice(100);
monitorState.setStock(1);
new PriceObserver().register(monitorState);
monitorState.setPrice(99);
monitorState.setPrice(98);
monitorState.setPrice(97);
}
}
- 您 购物车中的商品 库存紧张,剩余 1 件
- 您 购物车中的商品价格有新的变化 当前价格是 99.0 元
- 您 购物车中的商品价格有新的变化 当前价格是 98.0 元
- 您 购物车中的商品价格有新的变化 当前价格是 97.0 元