Java观察者模式

Java观察者模式定义对象间一对多的依赖关系,当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都得到通知并自动更新。JDK中提供的观察者模式的实现是由java.util.Observer接口和java.util.Observable类组成的,其中Observer代表观察者,而Observable代表被观察者。

Java观察者模式

Java观察者模式


1、Observable类是由被观察者(可有一个或多个观察者)所继承,调用setChanged方法,是的hasChanged方法返回值为true,则再次调用notifyObservers方法会触发观察者的update方法来通知观察者该实例发生变化。

Java观察者模式

2、Observer接口中只有一个为实现的update抽象方法,实现该接口的对象称为观察者,该对象要实现update方法。注册了该对象(观察者)的对象(被观察者)实例在调用notifyObservers方法之后,会自动调用观察者中的update方法。

Java观察者模式

3、被观察者I114gBoxHeaterObservable.java,代表热水器,继承Obserable,其实现如下:

/**
 * 
 */
package com.i114gbox.sdk.designMode.observer;

import java.util.Observable;

/**
 * 热水器--被观察者
 * 
 * @author shenjichao@vivagame.cn
 * 
 */
public class I114gBoxHeaterObservable extends Observable {

	// 水温
	private int temperature;

	public int getTemperature() {
		return temperature;
	}

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

	// 烧水
	public void boilWater() {
		for (int i = 10; i <= 100;) {// 初始水温为15度
			temperature = i;
			// 调用setChanged(),hasChanged()将返回true
			this.setChanged();
			// 当hasChanged()返回true时,监听被观察者的观察者将调用update()
			this.notifyObservers();
			i += 10;
		}
	}

}

4、在扮演观察者角色的同时,又扮演被观察者的角色,类名为I114gBoxDisplayObservable.java,代表显示器,继承Observable类,实现Observer接口,其实现如下:

/**
 * 
 */
package com.i114gbox.sdk.designMode.observer;

import java.util.Observable;
import java.util.Observer;
import java.util.logging.Logger;

/**
 * 显示器--观察者(用于观察热水器),被观察者(被报警器观察)
 * 
 * @author shenjichao@vivagame.cn
 * 
 */
public class I114gBoxDisplayObservable extends Observable implements Observer {
	private static Logger logger = Logger
			.getLogger(I114gBoxDisplayObservable.class.getSimpleName());

	private String status = I114gBoxWaterStatus.COLD.toString();

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	// 显示水温
	private void displayTemperature(int temperature) {
		// 当水被烧开时
		if (temperature == 100) {
			this.setStatus(I114gBoxWaterStatus.HOT.toString());
			this.setChanged();
			this.notifyObservers(temperature);
		}

		logger.info("水状态为:" + status + "|" + "现在水温为:" + temperature);
	}

	// 当被观察者状态发生改变时,调用该方法
	@Override
	public void update(Observable observable, Object data) {
		this.displayTemperature(((I114gBoxHeaterObservable) observable)
				.getTemperature());
	}

}

5、观察者I114gBoxAlarmObserver.java,代表报警器,实现Observer接口,其实现如下:

/**
 * 
 */
package com.i114gbox.sdk.designMode.observer;

import java.util.Observable;
import java.util.Observer;
import java.util.logging.Logger;

/**
 * 报警器--观察者
 * 
 * @author shenjichao@vivagame.cn
 * 
 */
public class I114gBoxAlarmObserver implements Observer {
	private static Logger logger = Logger.getLogger(I114gBoxAlarmObserver.class
			.getSimpleName());

	// 当水烧开了调用该方法
	@Override
	public void update(Observable observable, Object data) {
		this.makeAlarm((Integer) data);
	}

	// 报警
	private void makeAlarm(int temperature) {
		logger.info("滴滴滴……水烧开了!");
	}

}

6、观察者模式测试类Test.java,其实现如下:

/**
 * 
 */
package com.i114gbox.sdk.designMode.observer;

/**
 * 观察者模式测试类
 * 
 * @author shenjichao@vivagame.cn
 * 
 */
public class Test {

	public static void main(String[] args) {

		I114gBoxHeaterObservable heater = new I114gBoxHeaterObservable();
		I114gBoxDisplayObservable display = new I114gBoxDisplayObservable();
		I114gBoxAlarmObserver alarm = new I114gBoxAlarmObserver();

		// 加入观察者
		// 显示器用来观察热水器
		heater.addObserver(display);
		// 报警器用来观察显示器
		display.addObserver(alarm);

		// 烧水
		heater.boilWater();

	}

}

7、运行测试类,结果如下:

Java观察者模式


8、注意事项

   优点:

支持松耦合和减少依赖性;

观察者数目可变

   缺点:

性能降低;

内存泄露;

测试调试困难

Java观察者模式,布布扣,bubuko.com

Java观察者模式

上一篇:LRU缓存算法 - C++版


下一篇:【Shiro + Spring MVC整合】教程——权限控制