监听者模式实现对象通信

本文深入探讨了观察者模式的概念、实现原理及其在Java语言中的应用,通过具体实例展示了如何使用Java的Observable和Observer接口来实现观察者模式,包括Observer接口、Observable类的使用方法,以及实际操作中的代码实现和输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  什么是监听者模式?简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新。

  在Java语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成Java语言对观察者模式的支持。

  Observer接口

  这个接口只定义了一个方法,update()。当被观察者对象的状态发生变化时,这个方法就会被调用。这个方法的实现应当调用每一个被观察者对象的notifyObservers()方法,从而通知所有的观察对象。

  Observable类

  被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一个方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。

  下面我们举个列子看看,这个模式怎么用代码实现。

  1.Observer代码如下

public interface Observer {
	/**
	 * 当被观察的对象发生变化时,这个方法会被调用。
	 */
	void update(Observable o, Object arg);
}
  2.Observable代码如下

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

	/**
	 * 用0个观察者构造一个被观察者。
	 * 
	 * @return
	 **/

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

	/**
	 * 将一个观察者加到观察者列表上面。
	 */
	public synchronized void addObserver(Observer o) {
		if (!obs.contains(o)) {
			obs.addElement(o);
		}
	}

	/**
	 * 将一个观察者对象从观察者列表上删除。
	 */
	public synchronized void deleteObserver(Observer o) {
		obs.removeElement(o);
	}

	/**
	 * 相当于 notifyObservers(null)
	 */
	public void notifyObservers() {
		notifyObservers(null);
	}

	/**
	 * 如果本对象有变化(那时hasChanged 方法会返回true) 调用本方法通知所有登记在案的观察者,即调用它们的update()方法,
	 * 传入this和arg作为参量。
	 */
	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);
	}

	/**
	 * 将观察者列表清空
	 */
	public synchronized void deleteObservers() {
		obs.removeAllElements();
	}

	/**
	 * 将“已变化”设为true
	 */
	protected synchronized void setChanged() {
		changed = true;
	}

	/**
	 * 将“已变化”重置为false
	 */
	protected synchronized void clearChanged() {
		changed = false;
	}

	/**
	 * 探测本对象是否已变化
	 */
	public synchronized boolean hasChanged() {
		return changed;
	}

	/**
	 * 返还被观察对象(即此对象)的观察者总数。
	 */
	public synchronized int countObservers() {
		return obs.size();
	}

}
  3.具体被观察者的实现
public class ConcreteObservable extends Observable{

	public void sendMessageToAll(){
		setChanged();
		notifyObservers(new Message(data.xiaohei));
	}
}
  4.具体观察者的实现,我这边举个A和B的例子

public class AObserver implements Observer{

	public AObserver(){

	}
	@Override
	public void update(Observable o, Object arg) {
		Message result=(Message)arg;
		if(result!=null&&result.tag==Message.data.xiaohei){
			System.out.println("AObserver这个类正在处理");
		}
		
	}

}

public class BObserver implements Observer {
	public BObserver() {

	}

	@Override
	public void update(Observable o, Object arg) {
		Message result = (Message) arg;
		if (result != null && result.tag == Message.data.xiaowang) {
			System.out.println("BObserver这个类正在处理");
		}

	}
}
  5.定义具体被观察者中传递的消息对象
public class Message {

	public data tag;

	public Message(data tag) {
		this.tag = tag;
	}

	public static enum data {
		xiaowang, xiaohei
	}

}
  6.测试如下

public class Test {
	public static void main(String args[]) {
		ConcreteObservable co = new ConcreteObservable();
		Observer a = new AObserver();
		Observer b = new BObserver();
		co.addObserver(a);
		co.addObserver(b);
		co.sendMessageToAll();
	}
}
  7.输出结果如下

  AObserver这个类正在处理



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值