java设计模式入门(2)观察者模式

观察者模式的定义:定义了对象之间的一对多依赖,当一个对象改变时,它的所有依赖者都会收到通知并自动更新。

java源码中观察者模式以推和拉来传送数据。


这个类代表一个观察者对象或者是模型-视图范式中的数据。对象想被其他对象观察可以继承这个类。
一个可以被观察的对象可以有一个或多个的观察者(一对多)。
一个观察者可能是任何实现Observer接口的对象。
当一个被观察者实例改变之后,应用程序会调用Observable的notifyObservers方法导致所有的观察者调用自己的update方法做相应的改变。


通知传递的顺序是没有明确指定的。
默认实现提供被观察者类将会以它们注册兴趣顺序来通知的,但是子类可以改变这个顺序,当你在其他子线程中传递通知时,不确保传递顺序,或者是可能确保子类按照它们选
择的顺序。

java源码中的被观察者code:

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    public Observable() {
        obs = new Vector<>();
    }

    /**
     * 加入观察者 
     * @param   o   一个要被加入的观察者对象.
     * @throws NullPointerException   如果是null的.
     */
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    /**
     * 移除观察者
     * @param   o   the observer to be deleted.
     */
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    /**
     * 如果这个对象改变了,会通过hasChanged方法来表明的,接着通知所有的观察者之后又调用clearChanged方法表明该对象不再改变了。
     * 每个观察者有自己的update带有两个参数的方法(参数:Observable object,null).
     * 换句话说,该方法等同于notifyObservers(null)
     */
    public void notifyObservers() {
        notifyObservers(null);
    }

    /**
     * 通知观察者们,此参数根据客户端需求来传递
     */
    public void notifyObservers(Object arg) {

        Object[] arrLocal;

        synchronized (this) {
            /* 两大潜在竞争条件的缺点:
             * 1)最新增加的观察者可能错失这次的通知进程
             * 2) 最新移除观察者可能接收到通知
             */
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

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

    /**
     * 移除观察者
     */
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    /**
     * 标志被观察者已经改变了。
     */
    protected synchronized void setChanged() {
        changed = true;
    }

    /**
     * 标志被观察者不再改变
     */
    protected synchronized void clearChanged() {
        changed = false;
    }

    /**
     * 测试是否改变
     */
    public synchronized boolean hasChanged() {
        return changed;
    }

    /**
     * 返回观察者的个数
     * @return  观察者的个数
     */
    public synchronized int countObservers() {
        return obs.size();
    }
}

观察者,最主要的职责就是根据被观察者给的东西来进行自己的操作,所以抽象为一个接口,具体的观察者都要实现这个接口

java源码中观察者code:

/**
 * 当一个类想要被通知被观察者对象的改变时,可以实现这个接口
 */
public interface Observer {
    /**
     * 被观察者改变时这个方法会被调用,我们要重写这个方法,根据我们的业务需求来编写不同的代码
     * 
     * @param   o     被观察的对象,因为被观察的对象也不明确观察者们具体要的是什么东东,所以就把自己传递给所有的观察者.让观察者自己来获取自己感兴趣的。
     * @param   arg   .
     */
    void update(Observable o, Object arg);
}

接下来就是例子


一个天气可观察者,三个观察对象

可观察的对象:

import java.util.Observable;

public class WeatherObservable extends Observable {
	/** 温度 */
	private float temperature;
	/** 湿度 */
	private float moisture;
	/** 气压 */
	private float pressure;

	public float getPressure() {
		return pressure;
	}

	public void setPressure(float pressure) {
		this.pressure = pressure;
	}

	public float getTemperature() {
		return temperature;
	}

	public float getMoisture() {
		return moisture;
	}

	public void setMoisture(float moisture) {
		this.moisture = moisture;
	}

	public void setTemperature(float temperature) {
		this.temperature = temperature;
	}

	public void setProperity(float pressure, float moisture, float temperature) {
		this.pressure = pressure;
		this.moisture = moisture;
		this.temperature = temperature;
	}

	/** 设置为改变了 */
	public void setChanged() {
		super.setChanged();
	}
}

三个观察者:

观察湿度:

import java.util.Observable;
import java.util.Observer;

/** 观察温度 */
public class WatchTemperature implements Observer {

	@Override
	public void update(Observable o, Object arg) {
		if (o instanceof WeatherObservable) {
			float temperature = ((WeatherObservable) o).getTemperature();
			System.out.println("温度改变为:" + temperature);
		}
	}
}
import java.util.Observable;
import java.util.Observer;

/** 监听湿度 */
public class WatchMoisture implements Observer {

	@Override
	public void update(Observable o, Object arg) {
		if (o instanceof WeatherObservable) {
			float moisture = ((WeatherObservable) o).getMoisture();
			System.out.println("湿度改变为" + moisture);
		}
	}

}
import java.util.Observable;
import java.util.Observer;

/** 对气压感兴趣 */
public class WatchPressure implements Observer {

	@Override
	public void update(Observable o, Object arg) {
		if (o instanceof WeatherObservable) {
			float pressure = ((WeatherObservable) o).getPressure();
			System.out.println("气压改变了" + pressure);
		}
	}

}
测试类:

/** 测试类 */
public class Test {

	public static void main(String[] args) {

		WeatherObservable ob = new WeatherObservable();
		WatchTemperature watchTemperature = new WatchTemperature();
		WatchMoisture watchMoisture = new WatchMoisture();
		WatchPressure watchPressure = new WatchPressure();

		ob.addObserver(watchMoisture);
		ob.addObserver(watchPressure);
		ob.addObserver(watchTemperature);

		ob.setChanged();
		ob.setProperity(120, 30, 20);
		ob.notifyObservers();
	}

}




结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值