設計模式_觀察者模式


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接口,使用這倆個就顯得非常簡單了。

我是菜鳥,我在路上。
發佈了78 篇原創文章 · 獲贊 17 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章