Observer Pattern
Define a ont-to-many dependency between objects so that when
one object changes state,all its dependents are notified and updated automatically.(定義對象間一種一對多的依賴關係,使得每當一個對象改變狀態時,則所有依賴於它的對象都會得到通知並被自動更新)
● Subject被觀察者
定義被觀察者必須實現的職責,它必須能夠動態地增加、取消觀察者。它一般是抽象類 或者是實現類,僅僅完成作爲被觀察者必須實現的職責:管理觀察者並通知觀察者。
● Observer觀察者
觀察者接收到消息後,即進行update(更新方法)操作,對接收到的信息進行處理
public abstract class Subject {
//定義一個觀察者數組
private Vector<Observer> obsVector = new Vector<Observer>();
//增加一個觀察者
public void addObserver(Observer o){
this.obsVector.add(o);
}
//刪除一個觀察者
public void delObserver(Observer o){
this.obsVector.remove(o);
}
//通知所有觀察者
public void notifyObservers(){
for(Observer o:this.obsVector){
o.update();
}
}
}
例子
監控秦始皇,儒家,墨家,法家都嚴密監視秦始皇的行動。
public interface Observer {
public void update(String context);
}
/**
* 這個接口的存在就是對觀察者的統一管理
* @author suibian
*
*/
public interface ObserverManage {
public void addObserver(Observer observer);
public void deleteObserver(Observer observer);
public void notifyObservers(String context);
}
/**
* 被觀察者,該有的都有
* @author suibian
*
*/
public interface IEmperorQin {
public void haveLove();
public void haveUnited();
}
public class EmperorQin implements ObserverManage,IEmperorQin{
private ArrayList<Observer> observerList=new ArrayList<Observer>();
/*private Vector<Observer> observerList=new ArrayList<Observer>(); 這樣線程安全 */
public void addObserver(Observer observer) {
this.observerList.add(observer);
}
public void deleteObserver(Observer observer) {
this.observerList.remove(observer);
}
public void notifyObservers(String context) {
for(Observer ob:observerList){
ob.update(context);
}
}
public void haveLove() {
System.out.println("秦始皇開始修阿房宮了");
this.notifyObservers("秦始皇開始修阿房宮了");
}
public void haveUnited() {
System.out.println("秦始皇已經統一天下了");
this.notifyObservers("秦始皇已經統一天下了");
}
}
public class RuJia implements Observer {
public void update(String context) {
System.out.println("儒家:看到李斯活動,準備配合");
this.cry(context);
System.out.println("儒家配合的好");
}
private void cry(String context) {
System.out.println("儒家根據-》"+context+"制定了計劃");
}
}
public class MoJia implements Observer {
public void update(String context) {
System.out.println("墨家:觀察到秦始皇活動,自己也開始行動了");
this.cry(context);
System.out.println("墨家修好了機關獸");
}
private void cry(String context) {
System.out.println("墨家說,因爲-》"+context+"所以我必須馬上行動");
}
}
public class FaJia implements Observer {
public void update(String context) {
System.out.println("法家:觀察到秦始皇活動");
this.reportToQinShiHuang(context);
System.out.println("法家彙報完畢");
}
private void reportToQinShiHuang(String context) {
System.out.println("法家:秦始皇有活動-》"+context);
}
}
public class QinDynasty {
public static void main(String[] args) {
FaJia liSi=new FaJia();
MoJia wanSi=new MoJia();
RuJia rujia=new RuJia();
EmperorQin qinshihuang=new EmperorQin();
qinshihuang.addObserver(liSi);
qinshihuang.addObserver(wanSi);
qinshihuang.addObserver(rujia);
qinshihuang.haveLove();
qinshihuang.haveUnited();
}
}
/*
如果這樣設計,的確,訂閱模式,但是前提是觀察者需要被添加到被觀察者的隊列中
當被觀察者行動時,循環隊列,一個一個的調用隊列中的提醒方法,也就是說,被觀察者必須要知道觀察者中的內部結構,
或者說他們倆個達成了某種協議
擴展性不好
代碼結構清晰
*/
優點
觀察者和被觀察者是抽象耦合
觸發機制形成了一個觸發鏈
缺點
如果一個觀察者卡殼...
使用場景
關聯行爲
多級觸發
跨系統的消息交換
在java中已經有了一個java.util.Observer接口和 java.util.Observable接口,使用這倆個就顯得非常簡單了。
我是菜鳥,我在路上。