现在的位置: 首页 > 综合 > 正文

设计模式之观察者模式(二)

2018年02月05日 ⁄ 综合 ⁄ 共 3331字 ⁄ 字号 评论关闭

   先看定义 ,观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

  应用:j2se的AWT事件处理机制是基于观察者模式的,在Spring中的应用是事件传播机制。

  从定义中可以看出,所谓观察者模式,就必须有观察者和被观察者,当被观察者状态发生改变时(比如属性值改变等),所有观察者都得到通知并更新。

   这就非常类似事件处理机制,事件处理机制有事件和Listener,事件就像被观察者,当事件被触发的时,就相当于观察者状态改变,这是就自动触动Listener(被观察者)。

  先看java.util.Observe接口(观察者)

public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}
}

先不解释,看被观察者java.util.Observable

public class Observable {
    private boolean changed = false;
    private Vector obs;
   
    //创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。
    public Observable() {
	obs = new Vector();
    }

    /**
     * 添加观察者到观察者列表中去
     */
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
	if (!obs.contains(o)) {
	    obs.addElement(o);
	}
    }

    /**
     * 删除一个观察者
     */
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    /**
     * 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作,不传参数的通知方法
     */
    public void notifyObservers() {
	notifyObservers(null);
    }

    /**
     * 与上面的那个通知方法不同的是,这个方法接受一个参数,这个参数一直传到观察者里,以供观察者使用
     */
    public void notifyObservers(Object arg) {
	
        Object[] arrLocal;

	synchronized (this) {
	    if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }
}

ok,这里有个addObserve(Observe o)的方法,也就是说在这个方法里给被观察者添加观察者,当被观察者状态变化时,将调用notifyObservers(Object arg)方法,传的这个参数将传给观察者,以供观察者使用(改变属性或者做相应的事件处理)(所以观察者里有个UPDATE(Observable o,Object arg))。

观察者必须实现Observe 接口,被观察者必须继承Observable 

下面来一个实例 定义4个观察者,分别观察名字和价格属性

public class PriceObserver1 implements Observer{  
    public void update(Observable o, Object arg) {  
        System.out.println("PriceObserver1  价格改变为:"+arg);  
    }  
}
public class PriceObserver2  implements Observer{  
  
    public void update(Observable o, Object arg) {  
        System.out.println("PriceObserver2价格改变为:"+arg);  
    }  
}
public class NameObserver1 implements Observer{  
  
      
    public void update(Observable o, Object arg) {  
        System.out.println("NameObserver1  价格改变为:"+arg);  
    }  
}
public class NameObserver2 implements Observer{  
  
    public void update(Observable o, Object arg) {  
        System.out.println("NameObserver2 价格改变为:"+arg);  
    }  
}

再来一个被观察者

public class Product extends Observable{  
    
	 
	public String name;
	public int price;
	public Product(){}
	public  Product(String name,int price){
		this.name=name;
		this.price=price;
		
	}
	public String getName(){
		return this.name;
	}
	public void setName(String name){
		this.name=name;
	// 一旦改变name属性,就通知观察者
		notifyObservers(name);
	}
	    
	public int getPrice(){
		return this.price;
	}
	public void setPrice(int price){
		this.price=price;
	// 一旦改变name属性,就通知观察者
		notifyObservers(price);
	} 
	public static void main(String [] args) {  
        //创建一个被观察者  
        Product product = new Product ("aaa",1);  
        
        System.out.println("product name="+product.getName()+";price="+product.getPrice());
        
        //创建四个观察者  
        Observer priceObserver1= new PriceObserver1();  
        Observer priceObserver2= new PriceObserver2();  
        Observer nameObserver1= new NameObserver1();  
        Observer nameObserver2= new NameObserver2();  
          
        //把4个观察者加到被观察者列表中  
        product.addObserver(priceObserver1);  
        product.addObserver(priceObserver2);  
        product.addObserver(nameObserver1);  
        product.addObserver(nameObserver2); 
        product.setName("bbb");
        product.setPrice(2);
    }  
	    
	}  

这个例子很明显 被观察者的name或者price属性改变后,将通知观察者update(Observe o,object  obj)做出相应的响应。究其原因,是改变属性的时候,调用

notifyObservers

方法,这个方法是在被观察者的父类里定义的,父类里这方法又调用了观察者接口的update方法,这也就是观察者模式内部的玄机了,我说观察者咋就可以观察到被观察对象的改变呢,原来我们实现了观察者接口的update方法。


  

抱歉!评论已关闭.