隨筆 - 303  文章 - 883  trackbacks - 0
          <2007年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          歡迎光臨! 
          閑聊 QQ:1074961813

          隨筆分類(357)

          我管理的群

          公共blog

          • n維空間
          • Email : java3d@126.com 群 : 12999758

          參與管理的論壇

          好友的blog

          我的其他blog

          朋友的網站

          搜索

          •  

          最新評論

                   前面一個文章里的代碼很簡單(只是讓大家了解什么是代理),實現的是靜態代理,做為電腦代理商的ComputerProxy,在電腦行業 為電腦生產商(三星,聯想)和客戶提供服務,提供各種方便。
                  郁悶的是,如果我現在增加一個行業,比如下面要講到的Car汽車行業,那么,我們只能增加一個代理了,也就是說我們要再寫一個CarProxy代碼,我們現在假設我們有很多個行業,那么,無疑我們的工作量開始大了,有沒有什么辦法讓我們的代理商實現跨行業代理呢?
                  答案是:可以。這就是我們這里講的動態代理產生存在的意義了。

          請看代碼

          在原有代碼的基礎上我們做了這些寬展:

          /*
          *汽車批發商
          *這樣我們的代碼中就有了電腦和汽車這兩個批發商
          */

          public interface Car {
              
          public void buyCar(String name);
          }

          /*
          *勞斯萊斯汽車公司
          */

          public class RollsRoyce implements Car {

              
          public void buyCar(String name) {
                  
                  System.out.println(name
          +"  勞斯萊斯公司產品!");
              }


          }

          /*
          *所有行業代理商
          *有了它我們的客戶可以通過他買個各種產品
          */

          import java.lang.reflect.InvocationHandler;
          import java.lang.reflect.Method;
          import java.lang.reflect.Proxy;
          import java.util.logging.Level;
          import java.util.logging.Logger;

          public class AllthingsProxy implements InvocationHandler {

              
          private Logger logger=
                  Logger.getLogger(
          this.getClass().getName());
              
              
          private Object allthings;
              
              
          //實現對象綁定
              public Object bind(Object allthings){
                  
                  
          this.allthings = allthings;
                  
                  
          //這里傳入newProxyInstance的參數分別是 目標object
                  
          //(Lianxiang,Sanxing),interface(Computer),AllthingsProxy
                  return Proxy.newProxyInstance(allthings.getClass().getClassLoader(),
                                              allthings.getClass().getInterfaces(), 
          this);
              }

              
              
          public Object invoke(Object proxy, Method method, Object[] args)
                      
          throws Throwable {
                  
                  Object result 
          = null;
                  
                  
          try{
                  log(
          "method starts " + method);
                  
                  result
          =method.invoke(allthings, args);

                  logger.log(Level.INFO , 
          "method ends " + method);
                  
                  }
          catch(Exception e){
                      log(e.toString());
                  }

                  
                  
          return result;
              }

              
              
          private void log(String msg){
                  logger.log(Level.INFO,msg);
              }


          }


          在測試類BuyAllThings中,我們通過bing方法綁定對象(所要買的東西),讓代理商了解到,客戶想買什么?
          (這里重在了解模式,具體方法的實現如不了解請自行查詢API文檔)


          /*
          *三個客戶兩個買電腦一個買汽車
          *他們找到同個代理商
          */

          public class BuyAllThing {

              
          public static void main(String[] args) {
                  
                  AllthingsProxy allthingsproxy 
          = new AllthingsProxy();
                  
                  Computer SanxingProxy
          =(Computer)allthingsproxy.bind(new Sanxing());
                  
                  SanxingProxy.buyComputer(
          "我想買一臺三星電腦");
                  
                  Computer lianxiangProxy
          =(Computer)allthingsproxy.bind(new Lianxiang());
                  
                  lianxiangProxy.buyComputer(
          "我想買一臺聯想電腦");
                  
                  Car rRollsRoyceProxy
          =(Car)allthingsproxy.bind(new RollsRoyce());
                  
                  RollsRoyceProxy.buyCar(
          "我想買一輛勞斯萊斯汽車");

              }


          }

          執行結果

          我想買一臺三星電腦  三星電腦公司產品!
          我想買一臺聯想電腦  聯想電腦公司產品!
          我想買一輛勞斯萊斯汽車  勞斯萊斯公司產品!
          2007-8-9 13:08:41 com.lusm.spring.AllthingsProxy log
          信息: method starts 
          public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
          2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
          信息: method ends 
          public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
          2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy log
          信息: method starts 
          public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
          2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
          信息: method ends 
          public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
          2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy log
          信息: method starts 
          public abstract void com.lusm.spring.Car.buyCar(java.lang.String)
          2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
          信息: method ends 
          public abstract void com.lusm.spring.Car.buyCar(java.lang.String)

          我們可以任意的增加代理商的業務,比如,叫他代理電器,食物......,我們看到我們不需要更改原有的代碼。這是動態代理帶來的好處!

          那我們的AllthingsProxy是怎么作到動態代理的呢?

          AllthingsProxy寬展了InvocationHandler并實現了里面的代理方法,返回一個Object對象,

              public Object invoke(Object proxy, Method method, Object[] args)
              
          throws Throwable;

          來實現對汽車,電腦這些批發商的動態代理(代理商同過它 代理所有行業)。

          AllthingsProxy中的bind實現了客戶和代理商間的通信(通過它代理商知道客戶想要買什么)

          這和我們 BuyAllThing 測試類main中

          代理對象=(綁定對象)allthingsproxy.bind(綁定對象(客戶想買的東西))

          想對應。

                   呵呵 ,講完了!也許有的朋友看不懂這里在說什么? 不必著急,學習都需要過程,等你的學習到某個階段的時候,回頭想想,也許認識就會加深許多,本人覺得Java是比較高級的語言,自身的發展也只直遵循著軟件設計優化(代碼重用)方向發展,重視設計思想,而不是去改變語言的語法或接口api,這是許多語言所缺乏的,如一個在VC6中編寫的代碼,拿到Visual Studio2005,Visual Studio2008去運行很容易出現問題。

                 也許你并不清楚我在說什么?但是這一切會在你的Spring學習中漸漸清楚起來!

                 以后的代碼可能需要必要的IDE才能使用,本人使用的是:
                 MyEclipse6.0M1+Eclipse3.3 
                 數據庫用的是:
                Oralce10g或者Mysql6.0

                祝你好運氣?。。?br />






          地震讓大伙知道:居安思危,才是生存之道。
          posted on 2007-08-09 13:49 小尋 閱讀(1472) 評論(5)  編輯  收藏 所屬分類: j2se/j2ee/j2me

          FeedBack:
          # re: [系列] 說故事學設計模式 之 ::Java動態代理模式 :: 2009-03-15 19:14 neu
          挺好,思路清晰  回復  更多評論
            
          # re: [系列] 說故事學設計模式 之 ::Java動態代理模式 ::[未登錄] 2009-06-14 14:16 bc
          cat 和 car都分不清楚,還講什么設計模式.  回復  更多評論
            
          # re: [系列] 說故事學設計模式 之 ::Java動態代理模式 ::[未登錄] 2009-06-17 14:31 尋覓
          太不好意思老 改過來改過來
            回復  更多評論
            
          # re: [系列] 說故事學設計模式 之 ::Java動態代理模式 :: 2009-09-23 10:17 另一個天堂
          講得很好,只是我還是沒弄清動態代理相對于靜態代理的好處...
          呵呵,我再看一遍你的文章.
          順便說下,你這邊文章我準備轉載了~  回復  更多評論
            
          # re: [系列] 說故事學設計模式 之 ::Java動態代理模式 :: 2009-09-23 10:38 另一個天堂
          又看了一遍,基本搞定了,呵呵。謝謝樓主了!  回復  更多評論
            
          主站蜘蛛池模板: 得荣县| 台南县| 卓尼县| 镇康县| 甘孜县| 郸城县| 师宗县| 日照市| 白玉县| 库尔勒市| 通城县| 蒙山县| 三原县| 宾川县| 南部县| 清远市| 尉氏县| 偏关县| 密山市| 河津市| 罗源县| 白山市| 车险| 湘乡市| 无为县| 民丰县| 资中县| 平顺县| 嘉峪关市| 太仆寺旗| 壤塘县| 中宁县| 天台县| 乌鲁木齐市| 汕尾市| 瑞丽市| 林芝县| 周至县| 绩溪县| 敖汉旗| 哈巴河县|