隨筆-42  評(píng)論-578  文章-1  trackbacks-0

          Java的API中有兩組接口類(lèi)是用來(lái)寫(xiě)觀察者模式用的,分別是java.util.Observable、java.util.Observer和java.util.EventListener、Java.util.EventObject。本文并沒(méi)有直接使用到這些API,而是自定義一套觀察者模式中相關(guān)的接口類(lèi),且選取一個(gè)日常生活中常見(jiàn)的一個(gè)事件來(lái)說(shuō)明觀察者模式的使用。

          clip_image002[13]

          現(xiàn)實(shí)場(chǎng)景:有一名店(Shop),為了財(cái)物安全起見(jiàn),除了在店內(nèi)裝了攝像頭(Camera)來(lái)監(jiān)控店內(nèi)的總?cè)藬?shù)外,還聘請(qǐng)了一些門(mén)衛(wèi)(Camera)守在店門(mén)口,對(duì)來(lái)訪的客人進(jìn)行實(shí)名登記,即客人進(jìn)入時(shí)要記名,客人出店時(shí)也要記錄其離去。

          //Watcher接口:

          package simple.observer;

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

          public interface Watcher {

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

              
          public void takeAction(Object  msg);
              
          }


          //Watchable類(lèi):

          package simple.observer;

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

          /**
           * "被觀察對(duì)象" 的父類(lèi)
           * 
          @author rongxinhua
           *
           
          */

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

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

              }

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

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

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

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

              
          }

           
          //Shop類(lèi),繼承了Watchable類(lèi),Shop內(nèi)有什么動(dòng)靜,會(huì)通過(guò)調(diào)用父類(lèi)的notifyWatcher()方法通知觀察者。

          package simple.observer;

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

          /**
           * 店類(lèi),可被觀察的
           * 
          @author rongxinhua
           *
           
          */

          public class Shop extends Watchable {

              
          static String IN = "in";    //進(jìn)入
              static String OUT = "out";    //出去
              
              Set
          <String> personSet = new HashSet<String>();
              
          int pcount = 0;        //店內(nèi)總?cè)藬?shù)
              
              
          /**
               * 來(lái)訪登記
               * 
          @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(門(mén)衛(wèi)類(lèi))和Camera(攝像頭類(lèi))都屬于本例中的觀察者,負(fù)責(zé)觀察店內(nèi)外的動(dòng)靜,

          package simple.observer;

          /**
           * 門(mén)衛(wèi)(保安)類(lèi)
           * 
          @author rongxinhua
           *
           
          */

          public class Guard implements Watcher {
              
              
          private String name;    //門(mén)衛(wèi)姓名

              
          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 + "向管理處匯報(bào):“" + msg[1+ "”已進(jìn)入本店!");
                  }

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

              }

              

          }

           

          package simple.observer;

          /**
           * 攝像頭類(lèi)
           * 
          @author rongxinhua
           *
           
          */

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


              @Override
              
          public void takeAction(Object msg) {
                  System.out.println(
          "攝像頭" + id + "號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為" + msg[2+ "");
              }


          }


          //測(cè)試類(lèi)代碼:

          package simple.observer;

          public class Test02 {

              
          /**
               * 
          @param args
               
          */

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


          }

          運(yùn)行測(cè)試類(lèi),結(jié)果如下:
           1門(mén)衛(wèi)一號(hào)向管理處匯報(bào):“BlogJava”已進(jìn)入本店!
           2攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為1人
           3門(mén)衛(wèi)一號(hào)向管理處匯報(bào):“JavaEye”已進(jìn)入本店!
           4攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為2人
           5門(mén)衛(wèi)一號(hào)向管理處匯報(bào):“BlogJava”已走出本店!
           6攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為1人
           7攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為2人
           8攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為1人
           9攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為2人
          10門(mén)衛(wèi)二號(hào)向管理處匯報(bào):“容新華”已進(jìn)入本店!
          11攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為3人
          12門(mén)衛(wèi)二號(hào)向管理處匯報(bào):“CSDN”已走出本店!
          13攝像頭1號(hào)監(jiān)測(cè)到現(xiàn)在店內(nèi)總?cè)藬?shù)為2人



          本文原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處,謝謝!http://www.aygfsteel.com/rongxh7(心夢(mèng)帆影JavaEE技術(shù)博客)
              

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

          評(píng)論:
          # re: 寫(xiě)個(gè)觀察者模式(Observer Pattern)的例子 2009-12-21 16:04 | 新奇特產(chǎn)品
          看起來(lái)樓主是下過(guò)苦功夫的啊。呵呵,贊一個(gè)!  回復(fù)  更多評(píng)論
            
          # re: 寫(xiě)個(gè)觀察者模式(Observer Pattern)的例子 2010-11-18 17:48 | Darren
          @新奇特產(chǎn)品
          不錯(cuò)。  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 新丰县| 德惠市| 杂多县| 河东区| 高雄县| 龙里县| 化隆| 称多县| 锦州市| 达拉特旗| 彭泽县| 墨玉县| 泾阳县| 称多县| 共和县| 甘孜县| 孟州市| 栖霞市| 瑞安市| 吴江市| 张家港市| 金寨县| 霍邱县| 旬邑县| 湘潭市| 高尔夫| 龙门县| 南平市| 鄂托克旗| 洪雅县| 哈尔滨市| 静宁县| 德钦县| 沁水县| 苍南县| 田阳县| 余庆县| 延庆县| 廊坊市| 教育| 凤城市|