應用場景
- 觀察者模式有時也叫做發佈訂閱模式。
- 主要用於在關聯行爲之間建立一套觸發機制的場景(例如一些提醒業務、MQ等等)
- java.awt.Event 就是觀察者模式的一種,只不過 Java 很少被用來寫桌面程序。上面的比如點擊事件等等都是通過發佈訂閱綁定來觸發事件。
- 在spring 中ContextLoaderListener是實現了ServletContextListener接口,這個接口也是繼承的EventListener。這也是觀察者模式的代表。
java語言中,有一個接口Observer,以及它的實現類Observable,對觀察者角色進行了實現。我們通過這個api寫一個發佈訂閱
代碼
觀察者
public class EyeOfGod implements Observer {
private String name;
@Override
public void update(Observable o, Object arg) {
// 被觀察者信息(觀察多個的話可以通過類型判斷來最強轉)
ObserveAims observeAims = (ObserveAims) o;
// 給被觀察者發佈的信息
Question question = (Question)arg;
System.out.println(this.name+"給"+observeAims.getName()+"發佈了"+question.getMsg());
}
}
被觀察者
class ObserveAims extends Observable {
private String name;
void publishQuestion(Question question) {
System.out.println(this.name+ "收到了一條" + question.getMsg() + "的消息。");
setChanged();
notifyObservers(question);
}
}
消息信息類
class Question {
private String msg;
}
測試
public class Test {
public static void main(String[] args) {
EyeOfGod eyeOfGod=new EyeOfGod();
eyeOfGod.setName("老師");
ObserveAims observeAims =new ObserveAims();
observeAims.setName("小明");
Question question=new Question();
question.setMsg("寫作業");
eyeOfGod.update(observeAims,question);
observeAims.publishQuestion(question);
}
}
輸出--------------------
老師給小明發布了寫作業
小明收到了一條寫作業的消息。
優點
- 觀察者和被觀察者之間建立了一個抽象的耦合。
- 觀察者模式支持廣播通信。
缺點
- 觀察者之間有過多的細節依賴、提高時間消耗及程序的複雜度。
- 使用要得當,要避免循環調用。
總結
觀察者模式有很多寫法,現在主流比較簡單的寫法是通過google的guava包的@Subscribe註解
public class GuavaEvent {
@Subscribe
public void subscribe(String str){
// 可以編寫業務邏輯
System.out.println("執行subscribe方法,傳入的參數是:" + str);
}
}
public static void main(String[] args) {
//消息總線
EventBus eventBus = new EventBus();
GuavaEvent guavaEvent = new GuavaEvent();
eventBus.register(guavaEvent);
eventBus.post("傳入信息");
}
輸出------------------
執行subscribe方法,傳入的參數是:傳入信息