Java 语言使用 Observer/Observable 实现简单的观察者模式

观察者模式的简单概念

假设现在有A、B、C、D等四个独立的对象,其中B、C、D这三个对象想在A对象发生改变的第壹时间知道这种改变,以便做出相应的响应。
上面的这种情形,就是观察者模式。当然每個被观察者可以有多个观察者,每個观察者也可以有多个被观察者。观察者与被观察者也不是对立的,壹個对象可以观察其他对象,也可以被其他对象观察。

观察者模式的应用场景

为了更好的理解什么是观察者模式,下面列举壹些可能用到该模式的情形或例子:
(1)周期性任务。比如linux中的周期性任务命令crontab命令,win7 下的定时关机命令shutdown -s -t 1200(1200s后关机)。当预期系统时间到后,这些命令就可以通知相应的观察者激活相应的命令并执行对应操作。
(2)重新加载配置文件。现在做大型系统基本都会有配置文件,例如在SSH项目中每次修改配置文件后,都需要重新启动服务器才能使得新的配置文件生效,当然SSH中貌似已经提供了参数设置,当配置文件修改时,可以自动重新加载。

观察者模式相关的 Java 类

java.util.Observable //继承该类的子类是可以被观察的,在观察者模式中充当被观察者

API 中的相关说明如下:This class represents an observable object, or "data" in the model-view paradigm. It can be subclassed to represent an object that the application wants to have observed.

An observable object can have one or more observers. An observer may be any object that implements interface Observer. After an observable instance changes, an application calling the Observable's notifyObservers method causes all of its observers to be notified of the change by a call to their update method.

The order in which notifications will be delivered is unspecified. The default implementation provided in the Observable class will notify Observers in the order in which they registered interest, but subclasses may change this order, use no guaranteed order, deliver notifications on separate threads, or may guarantee that their subclass follows this order, as they choose.

Note that this notification mechanism is has nothing to do with threads and is completely separate from the wait and notify mechanism of class Object.

When an observable object is newly created, its set of observers is empty. Two observers are considered the same if and only if the equals method returns true for them.

如何实现简单的观察者模式

接下来我们实现壹個简单的被观察者类 ExampleObservable ,代码如下:

import java.util.Observable;

public class ExampleObservable extends Observable {
	int data = 0;
	
	public void setData(int data){
		this.data = data;
		this.setChanged();//标记此 Observable对象为已改变的对象
                this.notifyObservers();//通知所有的观察者
	}
}

再实现壹個观察者类 ExampleObserver,代码如下:
import java.util.Observable;
import java.util.Observer;

public class ExampleObserver implements Observer {
        //有被观察者发生变化,自动调用对应观察者的update方法
        @Override
	public void update(Observable object, Object argument) {
                //通过强制类型转换获取被观察者对象
                ExampleObservable example = (ExampleObservable)object;
		System.out.println("example.data changed, the new value of data is " + example.data);
	}
}

我们再写壹個简单的测试类来测试下它是否运行正确,代码如下:
public class Main {

	public static void main(String[] args) {
		ExampleObservable example = new ExampleObservable();
		example.addObserver(new ExampleObserver());//给example这个被观察者添加观察者,允许添加多個观察者
		example.setData(2);
		example.setData(-5);
		example.setData(9999);
	}
}
运行之后在控制台输出如下结果:
example.data changed, the new value of data is 2
example.data changed, the new value of data is -5
example.data changed, the new value of data is 9999
通过输出结果我们可以了解到,当 ExampleObservable 类的实例 example 的成员变量 data 的值发生改变时,ExampleObserver 对象 都能够监测到,然后调用 update() 方法打印壹句话到控制台,说明以上的结果是符合我们预期的。

既是观察者又是被观察者

对于壹個类而言,可以既是观察者又是被观察者,只要既继承 Observable 类,又实现 Observer 接口就可以了。接下来给出壹個类似的例子。例子中 ObserverA 和 ObserverB 既是观察者又是被观察者,它们互相监听着对方的改变。
//ObserverA.java
import java.util.Observable;
import java.util.Observer;

public class ObserverA extends Observable implements Observer {

	@Override
	public void update(Observable object, Object arg) {
		ObserverB observerB = (ObserverB)object;
		System.out.println("observerB changed, the new value of observerB.data is " + observerB.data);
		this.setChanged();
		this.notifyObservers();
	}
}

//ObserverB.java
import java.util.Observable;
import java.util.Observer;

public class ObserverB extends Observable implements Observer {

	int data = 0;
	@Override
	public void update(Observable object, Object arg) {
		System.out.println("ObserverB found that ObserverA changed...");
	}
	
	public void setData(int data){
		this.data = data;
		this.setChanged();
		this.notifyObservers();
	}
}

//Main.java
import net.oschina.bairrfhoinn.multiply.ObserverA;
import net.oschina.bairrfhoinn.multiply.ObserverB;

public class Main {

	public static void main(String[] args) {
		ObserverA a = new ObserverA();
		ObserverB b = new ObserverB();
		
		a.addObserver(b);
		b.addObserver(a);
		
		b.setData(2);
	}
}
运行之后的结果为:
observerB changed, the new value of observerB.data is 2
ObserverB found that ObserverA changed...
之所以会出现上述运行结果,最初 ObserverA 和 ObserverB 相互之间作为观察者与被观察者,但是 ObserverB 的实例 b 先调用的 setData() 方法,然后 ObserverA 的实例 a 观察到了这個变化,于是调用了本类的 update 方法打印出了第壹行,紧接着 ObserverA 的 update() 方法在方法体中声明了自己发生了变化,于是 ObserverB 观察了这個情况,也调用了自身的 update() 方法并打印了第二句话。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值