在形式上講,觀察者模式與回調模式有很大的相似之處,對兩者使用都不是很熟練的同學,可能會難以分辨。
觀察者模式
觀察者模式的簡單代碼實現如下:
public class ConcretSubject {
private List<Observer> observers = new ArrayList<>();
public void register(Observer observer) {
observers.add(observer);
}
public void call() {
for (Observer observer : observers) {
observer.oncall();
}
}
}
public interface Observer {
void oncall();
}
public class Main {
public static void main(String[] args) {
ConcretSubject subject = new ConcretSubject();
Observer observer = () -> System.out.println("observer");
subject.register(observer);
subject.call();
}
}
我們首先聲明一個被觀察對象。
然后建立多個觀察者。
將多個觀察者都注冊到被觀察者里面。一個被觀察者維護者一個觀察者列表。
當被觀察者數據更新時,將會遍歷這個列表中所有的觀察者,一次調用觀察者的觀察方法。
由此可見,在觀察者模式里面,我們的中心人物是被觀察者,被觀察者負責維護觀察者列表,被觀察者負責一一通知觀察者。
回調模式
回調函數的簡單代碼實現如下:
public class ConcretSubject {
private Callback callback;
public void register(Callback callback) {
this.callback = callback;
}
public void call() {
callback.onCall();
}
}
public interface Callback {
void onCall();
}
public class Main {
public static void main(String[] args) {
ConcretSubject subject = new ConcretSubject();
Callback callback = new Callback() {
@Override
public void onCall() {
System.out.println("call");
}
};
subject.register(callback);
subject.call();
}
}
通過對比,我們發現,觀察者模式和回調函數模式及其相似,差別僅在于在觀察者模式中,被觀察者維護這一個觀察者列表,而在回調模式中,“被觀察者”只是保存了一個“觀察者”。這就是形式上的終極區別。
也就是說,回調函數是一種特殊的觀察者模式,是一種一對一的觀察者模式。