隨筆-42  評論-578  文章-1  trackbacks-0

          Java的API中有兩組接口類是用來寫觀察者模式用的,分別是java.util.Observable、java.util.Observer和java.util.EventListener、Java.util.EventObject。本文并沒有直接使用到這些API,而是自定義一套觀察者模式中相關的接口類,且選取一個日常生活中常見的一個事件來說明觀察者模式的使用。

          clip_image002[13]

          現實場景:有一名店(Shop),為了財物安全起見,除了在店內裝了攝像頭(Camera)來監控店內的總人數外,還聘請了一些門衛(Camera)守在店門口,對來訪的客人進行實名登記,即客人進入時要記名,客人出店時也要記錄其離去。

          //Watcher接口:

          package simple.observer;

          /**
           * 觀察者接口
           * 
          @author rongxinhua
           *
           
          */

          public interface Watcher {

              
          /**
               * (接收到通知后,)觀察者采取行動
               * 
          @param msg
               
          */

              
          public void takeAction(Object  msg);
              
          }


          //Watchable類:

          package simple.observer;

          import java.util.HashSet;
          import java.util.Set;

          /**
           * "被觀察對象" 的父類
           * 
          @author rongxinhua
           *
           
          */

          public class Watchable {
              
              
          private Set<Watcher> watcherSet = new HashSet<Watcher>();
              
              
          /**
               * 通知觀察者
               * 
          @param params 通知的信息數組
               
          */

              
          protected void notifyWatchers(Object params){
                  
          for(Watcher watcher : watcherSet) {
                      watcher.takeAction(params);        
          //觀察者采取行動
                  }

              }

              
              
          /**
               * 增加觀察者
               * 
          @param watcher
               
          */

              
          protected void addWatcher(Watcher watcher){
                  watcherSet.add(watcher);
              }

              
              
          /**
               * 移除觀察者
               * 
          @param watcher
               
          */

              
          protected void removeWatcher(Watcher watcher) {
                  watcherSet.remove(watcher);
              }

              
          }

           
          //Shop類,繼承了Watchable類,Shop內有什么動靜,會通過調用父類的notifyWatcher()方法通知觀察者。

          package simple.observer;

          import java.util.HashSet;
          import java.util.Set;

          /**
           * 店類,可被觀察的
           * 
          @author rongxinhua
           *
           
          */

          public class Shop extends Watchable {

              
          static String IN = "in";    //進入
              static String OUT = "out";    //出去
              
              Set
          <String> personSet = new HashSet<String>();
              
          int pcount = 0;        //店內總人數
              
              
          /**
               * 來訪登記
               * 
          @param name
               
          */

              
          public void comeIn(String name){
                  personSet.add(name);
                  pcount 
          = personSet.size();
                  notifyWatchers(IN, name, pcount);    
          //通知觀察者
              }

              
              
          /**
               * 出店登記
               * 
          @param name 
               
          */

              
          public void getOut(String name){
                  personSet.remove(name);
                  pcount 
          = personSet.size();
                  notifyWatchers(OUT, name, pcount);    
          //通知觀察者
              }

              
          }


          //Guard(門衛類)和Camera(攝像頭類)都屬于本例中的觀察者,負責觀察店內外的動靜,

          package simple.observer;

          /**
           * 門衛(保安)類
           * 
          @author rongxinhua
           *
           
          */

          public class Guard implements Watcher {
              
              
          private String name;    //門衛姓名

              
          public Guard(){}
              
              
          public Guard(String name){
                  
          this.name = name;
              }

              
              @Override
              
          public void takeAction(Object  msg) {
                  
          if(msg[0].equals("in")){
                      System.out.println(
          this.name + "向管理處匯報:“" + msg[1+ "”已進入本店!");
                  }

                  
          else if(msg[0].equals("out")){
                      System.out.println(
          this.name + "向管理處匯報:“" + msg[1+ "”已走出本店!");
                  }

              }

              

          }

           

          package simple.observer;

          /**
           * 攝像頭類
           * 
          @author rongxinhua
           *
           
          */

          public class Camera implements Watcher {
              
              
          private int id;        //攝像頭編號
              
              
          public Camera(int id){
                  
          this.id = id;
              }


              @Override
              
          public void takeAction(Object msg) {
                  System.out.println(
          "攝像頭" + id + "號監測到現在店內總人數為" + msg[2+ "");
              }


          }


          //測試類代碼:

          package simple.observer;

          public class Test02 {

              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  Shop shop 
          = new Shop();
                  
                  
          //添加攝像頭1號
                  Camera camera = new Camera(1);
                  shop.addWatcher(camera);
                  
                  
          //添加門衛一號
                  Guard guard1 = new Guard("門衛一號");
                  shop.addWatcher(guard1);
                  
                  
          //來訪登記、出門登記
                  shop.comeIn("BlogJava");
                  shop.comeIn(
          "JavaEye");
                  shop.getOut(
          "BlogJava");
                  
                  
          //移除門衛一號,派他去做別的事
                  shop.removeWatcher(guard1);    
                  
                  
          //進入無人觀察狀態,隨進隨出
                  shop.comeIn("CSDN");
                  shop.getOut(
          "JavaEye");
                  shop.comeIn(
          "心夢帆影");
                  
                  
          //添加門衛二號
                  Guard guard2 = new Guard("門衛二號");
                  shop.addWatcher(guard2);
                  
                  
          //來訪登記,出門登記
                  shop.comeIn("容新華");
                  shop.getOut(
          "CSDN");
                  
              }


          }

          運行測試類,結果如下:
           1門衛一號向管理處匯報:“BlogJava”已進入本店!
           2攝像頭1號監測到現在店內總人數為1人
           3門衛一號向管理處匯報:“JavaEye”已進入本店!
           4攝像頭1號監測到現在店內總人數為2人
           5門衛一號向管理處匯報:“BlogJava”已走出本店!
           6攝像頭1號監測到現在店內總人數為1人
           7攝像頭1號監測到現在店內總人數為2人
           8攝像頭1號監測到現在店內總人數為1人
           9攝像頭1號監測到現在店內總人數為2人
          10門衛二號向管理處匯報:“容新華”已進入本店!
          11攝像頭1號監測到現在店內總人數為3人
          12門衛二號向管理處匯報:“CSDN”已走出本店!
          13攝像頭1號監測到現在店內總人數為2人



          本文原創,轉載請注明出處,謝謝!http://www.aygfsteel.com/rongxh7(心夢帆影JavaEE技術博客)
              

          posted on 2009-12-20 19:37 心夢帆影 閱讀(3054) 評論(3)  編輯  收藏

          評論:
          # re: 寫個觀察者模式(Observer Pattern)的例子 2009-12-21 16:04 | 新奇特產品
          看起來樓主是下過苦功夫的啊。呵呵,贊一個!  回復  更多評論
            
          # re: 寫個觀察者模式(Observer Pattern)的例子 2010-11-18 17:48 | Darren
          @新奇特產品
          不錯。  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

                  歡迎光臨我的博客,本博客文章均為個人原創,歡迎提出寶貴的意見和建議!(容新華)

          <2009年12月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          隨筆分類(61)

          三人行

          常用網站

          搜索

          •  

          積分與排名

          • 積分 - 476900
          • 排名 - 107

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 德令哈市| 云林县| 张家港市| 宿松县| 宁波市| 龙南县| 固安县| 团风县| 洱源县| 霍林郭勒市| 屯昌县| 永仁县| 尼勒克县| 岳西县| 通辽市| 梅河口市| 阜南县| 西青区| 乐都县| 什邡市| 德阳市| 明光市| 海兴县| 名山县| 自治县| 三门县| 温泉县| 台江县| 崇仁县| 瑞丽市| 额尔古纳市| 外汇| 新郑市| 乐东| 辽阳县| 确山县| 泾川县| 阳曲县| 崇文区| 通辽市| 芮城县|