我理解的设计模式之观察者模模式

来源:互联网 发布:数据新闻报道方向 编辑:程序博客网 时间:2024/05/18 02:05

欢迎批评建议,共同进步

观察者模式:
一个被观察者管理所有相依于它的观察者物件,并且在本身的状态改变时主动发出通知。这通常通过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
角色:

抽象被观察者角色:把所有对观察者对象的引用保存在一个集合中,每个被观察者角色都可以有任意数量的观察者。被观察者提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。

抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。

具体被观察者角色:在被观察者内部状态改变时,给所有登记过的观察者发出通知。具体被观察者角色通常用一个子类实现。

具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

直接吧java的源码copy来分析下

被观察者角色
public class Observable {
private boolean changed = false;//这里是一个flgs
private Vector obs;//存储观察者的集合

/** Construct an Observable with zero Observers. */public Observable() {    obs = new Vector<>();}/** *这里就是添加观察者的方法 * * @param   o   an observer to be added. * @throws NullPointerException   if the parameter o is null. */public synchronized void addObserver(Observer o) {    if (o == null)        throw new NullPointerException();    if (!obs.contains(o)) {        obs.addElement(o);    }}/** *移除观察者 * Deletes an observer from the set of observers of this object. * Passing <CODE>null</CODE> to this method will have no effect. * @param   o   the observer to be deleted. */public synchronized void deleteObserver(Observer o) {    obs.removeElement(o);}/** *  * *这里罗罗了不少英文直接删除,就是重用代码,不传参数过来 * */public void notifyObservers() {    notifyObservers(null);} /**  *重点来啦,这里将观察者便利,然后通知观察者  *  *  */public void notifyObservers(Object arg) {    /*     * a temporary array buffer, used as a snapshot of the state of     * current Observers.     */    Object[] arrLocal;    synchronized (this) {        /* We don't want the Observer doing callbacks into         * arbitrary code while holding its own Monitor.         * The code where we extract each Observable from         * the Vector and store the state of the Observer         * needs synchronization, but notifying observers         * does not (should not).  The worst result of any         * potential race-condition here is that:         * 1) a newly-added Observer will miss a         *   notification in progress         * 2) a recently unregistered Observer will be         *   wrongly notified when it doesn't care         */        if (!changed)//这里是判断这个标志changed            return;        arrLocal = obs.toArray();//toArray        clearChanged();//改变状态为true    }    for (int i = arrLocal.length-1; i>=0; i--)//这里通知        //调用观察者的接口更新  第一个参数是当前的对象,地二个是        //要传递的数据        ((Observer)arrLocal[i]).update(this, arg);}/** * Clears the observer list so that this object no longer has any observers. */public synchronized void deleteObservers() {    obs.removeAllElements();}/** *改变状态为true * <tt>hasChanged</tt> method will now return <tt>true</tt>. */protected synchronized void setChanged() {    changed = true;}/** * Indicates that this object has no longer changed, or that it has * already notified all of its observers of its most recent change, * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>. * This method is called automatically by the * <code>notifyObservers</code> methods. * * @see     java.util.Observable#notifyObservers() * @see     java.util.Observable#notifyObservers(java.lang.Object) */protected synchronized void clearChanged() {    changed = false;}/** * Tests if this object has changed. * * @return  <code>true</code> if and only if the <code>setChanged</code> *          method has been called more recently than the *          <code>clearChanged</code> method on this object; *          <code>false</code> otherwise. * @see     java.util.Observable#clearChanged() * @see     java.util.Observable#setChanged() */public synchronized boolean hasChanged() {    return changed;}/** * Returns the number of observers of this <tt>Observable</tt> object. * * @return  the number of observers of this object. */public synchronized int countObservers() {    return obs.size();}

}


观察者
/**
* A class can implement the Observer interface when it
* wants to be informed of changes in observable objects.
*
* @author Chris Warth
* @see java.util.Observable
* @since JDK1.0
*/
public interface Observer {
/**
*
*这里同意一个更新的抽象方法
*
* @param o the observable object.
* @param arg an argument passed to the notifyObservers
* method.
*/
void update(Observable o, Object arg);
}

具体实现:
/**
* 被观察者
* @author lizhen
*
*/
public class Subject extends Observable {
private int date;

public int getDate() {    return date;}public void setDate(int date) {    //更新数据    this.date = date;    //置更新数据标志    setChanged();    //通知各个具体的观察者,这里有推数据的作用    notifyObservers(null);}

}

/**
* 观察者
* @author lizhen
*
*/
public class Observer implements java.util.Observer {

@Overridepublic void update(Observable o, Object arg) {    Subject observer=(Subject) o;    System.out.println("我是观察者1号:"+arg+"我改变的数据:"+observer.getDate());}

}

/**
* 观察者2
* @author lizhen
*
*/
public class Observer2 implements Observer {

@Overridepublic void update(Observable o, Object arg) {    Subject observer=(Subject) o;    System.out.println("我是观察者2号:"+arg+"我改变的数据:"+observer.getDate());}

}

/**
* 测试
* @author lizhen
*
*/
public class main {

public static void main(String[] args) {    Subject subject=new Subject();    Observer observer=new Observer();    Observer2 observer2=new Observer2();    subject.addObserver(observer);//添加观察者1号    subject.addObserver(observer2);//添加观察者2号    subject.setDate(88);//改变数据}

}

然后debug下,一步步跑一下 就全明白啦

适用场景
1) 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2) 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3) 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。

阅读全文
0 0