大話設計模式二十三章經(二) 訪問者模式(Visitor Pattern)

越獄專業戶邁克爾-斯科菲爾德最近手頭比較緊,叫來了2個越獄跟班越獄犯甲和越獄犯乙輕輕鬆鬆的搞定了阿爾法銀行其中的一處保險庫,拿到了一筆不菲的財寶,繼續他的亡命生涯.整個行動利落乾脆,不留一絲痕跡,真可謂越獄偷盜組織多面手!行動前的晚上,參考了設計模式二十三章經第七式--訪問者模式,制定了詳細周密的行動計劃.阿爾法銀行的保險庫只允許持有授權的許可證才能進去,你銀行老闆來了沒許可證照樣不準進,當然每張許可證的權限不一樣,在保險庫的可操作範圍也不一樣,米帥搞到了張銀行副總王大胖的許可證,當然這許可證是複製版的,原版的還在王大胖那裏.王大胖的這張許可證可謂權限強大,可以自由進出阿爾法銀行旗下的多家保險庫的任何地方,唯一不能進的就是銀行老總私人保險庫了.順便把其他的2張複製好的許可證給了越獄犯甲和越獄犯乙.

第二天一大早,斯科菲爾德一夥開始行動.憑着許可證進入了阿爾法銀行的其中一個保險庫裏,保險庫裏的櫃子有很多,斯科菲爾德打開藏有1661年英王查理二世加冕典禮上製成的權仗上鑲嵌的"非洲之星第I"鑽石那個櫃子,拿到了鑽石,越獄犯甲的那張許可證只能打開藏有白金的保險櫃,越獄犯乙更慘,試來試去最後終於打開個保險櫃,裏面只有一隻皮包,包裏空空如也..

下面這段JAVA代碼是站在程序的角度上來實現上面的故事中所用到的訪問者模式,這裏爲了便於讀者更好的理解該設計模式,全部用中文命名.

//阿爾法銀行所有的保險庫都必須符合這個標準
      interface 保險庫{
          void accept(許可證 許可證實例);
      }

//符合阿爾法銀行保險庫標準的旗下一家保險庫
      class 保險庫A implements 保險庫{
          private String 非洲之星鑽石;
          private String 白金保險櫃;
          private String 皮包;

    public 保險庫A(String 非洲之星鑽石,String 白金保險櫃,String 老總二奶照){

           this.非洲之星鑽石=非洲之星鑽石;

           this.白金保險櫃=白金保險櫃;

           this.皮包=皮包;

    }
          public void accept(許可證 許可證實例){
                 許可證實例.訪問(this);
          }
          public String get非洲之星鑽石() {
                return 非洲之星鑽石;
          }
          public void set非洲之星鑽石(String 非洲之星鑽石) {
                this.非洲之星鑽石 = 非洲之星鑽石;
          }
          public String get白金保險櫃() {
                return 白金保險櫃;
          }
          public void set白金保險櫃(String 白金保險櫃) {
                this.白金保險櫃 = 白金保險櫃;
          }
          public String get皮包() {
                return 皮包;
          }
          public void set皮包(String 皮包) {
                this.皮包 = 皮包;
          }
       }
      //阿爾法銀行所有的保險庫許可證都必須符合這個標準
        interface 許可證{
              void 訪問(保險庫 保險庫實例);
        }

        //邁克爾拿到的那張許可證 
        class 許可證A implements 許可證{
              public void 訪問(保險庫 保險庫實例){

                       保險庫A 保險庫A實例=(保險庫A)保險庫實例;
                       System.out.println("得到"+保險庫A實例.get非洲之星鑽石());
              }
        }
      //越獄犯甲拿到的那張許可證
         class 許可證B implements 許可證{
              public void 訪問(保險庫 保險庫實例){

                       保險庫A 保險庫A實例=(保險庫A)保險庫實例;

                       System.out.println("得到"+保險庫A實例.get白金保險櫃());
               }
         }
      //越獄犯乙拿到的那張許可證
        class 許可證C implements 許可證{
               public void 訪問(保險庫 保險庫實例){

                       保險庫A 保險庫A實例=(保險庫A)保險庫實例;

                       System.out.println("得到"+保險庫A實例.get皮包());
               }
        }

   public class Test{
         public static void main(String[] args) {
                保險庫A 保險庫A實例=new 保險庫A("非洲之星鑽石","白金保險櫃","皮包");
                許可證A 許可證A實例=new 許可證A();
                許可證B 許可證B實例=new 許可證B();
                許可證C 許可證C實例=new 許可證C();
                保險庫A實例.accept(許可證A實例);
                保險庫A實例.accept(許可證B實例);
                保險庫A實例.accept(許可證C實例);
                }
          }

 輸出結果爲:

       得到非洲之星鑽石

       得到白金保險櫃

       得到皮包

上面的代碼經測試可以正常運行,直接把代碼拷到Eclipse裏運行即可!

這裏總結一下訪問者模式,當一個類這裏暫且稱爲類A經常需要更換行爲或者添加新的行爲的時候,但我們又不想經常修改類A本身,我們可以把一些需要添加的行爲定義在新的類中,這些類都符合類A的的訪問接口,它們自身可以通過注入類A,來訪問類A的一些屬性,並且管理和操作這些屬性,來實現類A的一些新的行爲。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章