观察者模式(Observer)就是将观察者和被观察的对象分离开。我这里着试着在mvc架构下(model-view-control)来说说观察者模式,业务数据由数据模型(model)表示,视图(view)可以作为数据模型观察者,控制器(control)是数据模型和视图对象的通信者。业务数据是被观察者,控制器(control)观察业务数据的变化,发现数据变化后,就显示在界面上。观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,数据模型(model)是被观察对象,控制器(control)是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。
场景:网上商店中商品在名称、价格等方面有变化,希望系统能自动通知会员.
这就需要在商品product中加入Observer这样角色,以便product细节发生变化时,Observer能自动观察到这种变化,并能进行及时的update或notify动作.在Java的java.util包中有一个内嵌的观察者Observer接口,他只有一个方法:
public void update(Observable o,Object arg);
当被观察者对象发生变化时即调用该方法。他的第二个参数用于描述变化的特性。
面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
首先控制器(control)要想得到商品在名称、价格等方面有变化,根据面向对象设计的原则,定义两个类:NameObserver和PriceObserver.NameObserver主要用来对产品名称(name)进行观察的;PriceObserver主要用来对产品价格(price)进行观察的;这两个类必须实现一个接口Observer;这两个类还必须将自己注册到被观察对象(Subject)中,这个工作由控制器(control)完成。
public class NameObserver implements Observer{
private String name = "";
public void update(Observable obj, Object arg) {
if(arg instanceof String){
name=(String)arg;
System.out.println("NameObserver :name changet to "+name);
}
}
}
public class PriceObserver implements Observer{
private float price = 0;
public void update(Observable obj, Object arg) {
if (arg instanceof Float) {
price = ((Float) arg).floatValue();
System.out.println("PriceObserver:price changet to"+ price);
}
}
}
public class ProductControl{
private Product product;
public setProduct(Product product){
this.product = product;
}
public register(PriceObserver priceObsv,NameObserver nameObsv){
//加入观察者
product.addObserver(nameobs);
product.addObserver(priceobs);
}
public void removeNameObserver(PriceObserver priceObsv){
product.deleteObserver(nameobs);
}
public void removePriceObserver(NameObserver nameObsv){
product.deleteObserver(priceobs);
}
}
下面是具体的被观察对象商品,这个对象extends Observable类(java中内嵌的),当商品在名称、价格等方面有变化,就会发送通知.
public class Product extends Observable{
private String name;
private float price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers(name);
}
public float getPrice(){ return price;}
public void setPrice(float price){
this.price=price;
//设置变化点
setChanged();
notifyObservers(new Float(price));
}
}
数据变化后,显示在界面上的工作比较复杂.省略.
测试代码如下:
public class Test {
public static void main(String args[]){
ProductControl productControl=new ProductControl();
NameObserver nameobs=new NameObserver();
PriceObserver priceobs = new PriceObserver();
Product product = new Product();
productControl.setProduct(product);
productControl.register(nameobs,priceobs);
product.setName("橘子");
product.setPrice(1.22f);
}
}