1.观察者(发布-订阅)模式定义
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新
2.应用场景
当多个对象需要及时获取对象A的状态时,通过A的订阅方法订阅它,然后当A状态发生变化时通过其通知方法通知到各个订阅它的对象。
3.实现原理
其基本实现原理是 接口回调。
4.代码实例:
定义观察者接口
/**
* 观察者
* @author huolala-sunyan
*
*/
public interface Observer {
void update(Observable o, Object arg);
}
定义被观察者
/**
* 被观察者
* @author huolala-sunyan
*
*/
public class Observable {
private boolean changed = false;
private final List<Observer> observers;
public Observable(){
observers = new ArrayList<>();
}
public synchronized void addObserver(Observer o){
if(o == null){
throw new NullPointerException();
}
if(!observers.contains(o)){
observers.add(o);
}
}
public synchronized void deleteObserver(Observer o){
observers.remove(o);
}
public void clearObservers(){
observers.clear();
}
public void notifyObservers(Object arg){
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Observer[] arrLocal;
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary Observables while holding its own Monitor.
* The code where we extract each Observable from
* the ArrayList and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
*
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!hasChanged())
return;
arrLocal = observers.toArray(new Observer[observers.size()]);
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
arrLocal[i].update(this, arg);
}
protected synchronized void setChanged(){
changed = true;
}
protected synchronized void clearChanged() {
changed = false;
}
public synchronized boolean hasChanged() {
return changed;
}
}
观察者实例:
public class User implements Observer{
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
System.out.println(arg.toString());
}
}
被观察者实例:
public class NewsPager extends Observable{
public NewsPager(){
//注册User
User user = new User();
addObserver(user);
}
}
测试实例:
public class ObserverModeTest {
public static void main(String[] args){
NewsPager newspager = new NewsPager();
User user = new User();
newspager.setChanged();
newspager.notifyObservers("hahahaha");
}
}
输出结果: