观察者模式
介绍
观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。 --百度百科
观察者模式是一种对象行为模式。当然必须存在两种对象,观察者和被观察值,当被观察者行为状态发生变化,观察者则会被通知到并根据预设的逻辑产生相应的行为变化。
观察者模式更像是一种发布订阅关系,比如微信公众号订阅和微博关注,当公众号或者博主发布消息时,订阅者就会收到消息通知。该模式主要目的就是解耦合,使观察者与被观察者分离开。
当然也可以有多个观察者与多个被观察者,一个对象可以作为观察者,也可以被其他对象所观察。
Java中的观察者应用
jdk为我们提供了观察者模式的java类
- java.util.Observable(被观察者继承)
public class Observable {
private boolean changed = false; // 变化标识
private Vector<Observer> obs; // 观察者集合
/** Construct an Observable with zero Observers. */
public Observable() {
obs = new Vector<>();
}
/**
* 添加观察者对象
*/
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/**
* 删除观察者对象
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
/**
* 当被观察者发生变化,通知所有的观察者
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* 当被观察者发生变化,通知所有观察者
* @param arg any object.更新的对象信息
*/
public void notifyObservers(Object arg) {
/*
* 临时缓存数组,相当于当前观察者状态的快照
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal;
synchronized (this) {
/*
* 同步代码块
* 1)避免新添加观察者错过通知
* 2)避免最近取消订阅的观察者错误通知
*/
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
//遍历所有观察者并调用其update方法
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;
}
/**
* 获取当前观察者个数.
*/
public synchronized int countObservers() {
return obs.size();
}
}
- java.util.Observer(观察者接口实现)
public interface Observer {
/**
* 当订阅的被观察者发出通知执行该方法
*/
void update(Observable o, Object arg);
}
观察者需要重写Observer的update方法。被观察者通过addObservers方法添加观察者
HelloWorld
场景:智能家居
当下班回家时打开门(通知)开启空调电视,开灯。
观察者对象
- 空调
public class AirConditioner implements Observer{
@Override
public void update(Observable o, Object arg) {
System.out.println("打开空调");
}
}
- 电视
public class Television implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("打开电视");
}
}
- 灯
public class Light implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("打开灯");
}
}
被观察者
public class Master extends Observable {
public void openDoor(){
System.out.println("回到家打开门");
// 修改状态
this.setChanged();
this.notifyObservers();
}
}
通知测试
public class Test {
public static void main(String[] args) {
//创建观察者
Light light = new Light();
Television television = new Television();
AirConditioner airConditioner = new AirConditioner();
//创建被观察者
Master master = new Master();
//添加观察者
master.addObserver(light);
master.addObserver(television);
master.addObserver(airConditioner);
// 行为改变,发布通知
master.openDoor();
}
}
观察者模式其实很容易理解,状态的改变然后通知观察者做出相应的逻辑处理。同一个观察者也可以订阅多个被观察者。可以简单的理解为发布订阅关系
浙公网安备 33010602011771号