一、定义
观察者模式(发布-订阅模式):一种一对多的依赖关系,让多个广场这对象同时监听某一个主题对象。这个主题对象在状态发生变化是,会通知所有观察者对象,使他们能够自动更新自己。这是一种对象之间松耦合的方式。
二、机构图
三、使用场景和特点
使用场景:
当一个对象改变时需要同时改变其他多个对象,而且它不知道具体有多少对象有待改变,就应该考虑使用观察者模式。
作用:
观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
四、使用实例
Java中为我们提供了观察者模式的通用实现,Observable 可对应结构图中的Subject,
package java.util;
public class Observable {
private boolean changed = false;
private Vector<Observer> obs;
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);
}
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();
}
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();
}
}
package java.util;
public interface Observer {
void update(Observable o, Object arg);
}
package com.study.design.mode.samples;
import java.util.Observable;
import java.util.Observer;
public class ConcreteObserverA implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者A收到通知被更新了..." + arg);
}
}
package com.study.design.mode.samples;
import java.util.Observable;
import java.util.Observer;
public class ConcreteObserverB implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者B收到通知被更新了..." + arg);
}
}
package com.study.design.mode.samples;
import java.util.Observable;
public class ObserverSample {
public static void main(String[] args) {
Observable concreteSubject = new Observable() {
public synchronized void notifyObservers(Object data) {
setChanged();
super.notifyObservers(data);
}
};
concreteSubject.addObserver(new ConcreteObserverB());
concreteSubject.addObserver(new ConcreteObserverA());
concreteSubject.notifyObservers("change1");
concreteSubject.notifyObservers("change2");
}
}
运行结果:
观察者A收到通知被更新了...change1
观察者B收到通知被更新了...change1
观察者A收到通知被更新了...change2
观察者B收到通知被更新了...change2