Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
          關鍵字: 設計模式       

          代理模式:為其他對象提供一種代理以控制對這個對象的訪問.說白了就是,在一些情況下客戶不想或不能直接引一個對象,而代理對象可以在客戶和目標對象之間起到中介作用.去掉客戶不能看到的內容和服務或都增添客戶需要的額外服務.
          給大家舉個比較簡單的例子:
          假如你買臺IBM的筆記本,IBM產家是不提供鼠標的.但是我們如果從代理商的手里買就有鼠標和送.
          很簡單的例子,寫幾個類來實現一下吧.
          首先設計一個購買的接口代碼如下:(ComputerInterface.java)
          package test.lyx;
          publicinterface ComputerInterface {
          publicvoid buy();
          }
          建一個電腦類實現購買的接口代碼如下:(Computer.java)
          package test.lyx;
          publicclass Computer implements ComputerInterface{
          private String pcName="IBMT60";
          privateintpcPrice=17800;
          public String getPcName() {
          returnpcName;
          }
          publicvoid setPcName(String pcName) {
          this.pcName = pcName;
          }
          publicint getPcPrice() {
          returnpcPrice;
          }
          publicvoid setPcPrice(int pcPrice) {
          this.pcPrice = pcPrice;
          }
          publicvoid buy() {
          System.out.print("獲得筆記本電腦:"+pcName+"一臺");
          }
          }
          再建設一個代理商的類:用來完成買電腦和贈送鼠標:(ComputerProxy.java)
          package test.lyx;
          publicclass ComputerProxy {
          private ComputerInterface pci;
          public ComputerInterface getPci() {
          returnpci;
          }
          publicvoid setPci(ComputerInterface pci) {
          this.pci = pci;
          }
          publicvoid buy(){
          pci.buy();
          System.out.println("贈送鼠標一個");
          }
          }
          建一個主函數測試一下吧:(TestDemo.java)
          package test.lyx;
          publicclass TestDemo {
          publicstaticvoid main(String[] args) {
          ComputerProxy c1=new ComputerProxy();
          c1.setPci(new Computer());
          c1.buy();
          }
          }
          運行結果如下:
          獲得筆記本電腦:IBMT60一臺獲得鼠標一個
          以上就是代理功能的實現,由代理商銷售筆記本,并贈送鼠標.但是這樣的程序只適合是銷售IBM筆記本.那么如果要是其它品牌呢.所以我們來更改一個代理類.來實現動態的代理.
          建立一個類代碼如下:(ComputerProxy2.java)
          package test.lyx;
          import java.lang.reflect.InvocationHandler;
          import java.lang.reflect.Method;
          import java.lang.reflect.Proxy;
          publicclass ComputerProxy2 implements InvocationHandler{
          private Object delegate;
          //描述是誰的代理,也就是與那個類有關系
          public Object bind(Object delegate){
          this.delegate=delegate;
          return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(),this);
          }
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          System.out.println("贈送鼠標一個!");
          Object result=method.invoke(delegate, args);
          return result;
          }
          }
          然后在主函數中加上:
          ComputerProxy2 c2=new ComputerProxy2();
          ComputerInterface ci2=(ComputerInterface)c2.bind(new Computer());
          ci2.buy();
          就可以實現動態代理了.
          [b][/b]

          最后更新:2007-07-06 19:12
          14:46  |   永久鏈接  |   瀏覽 (7023)  |   評論 (20)  |    收藏  |   java  |   進入論壇  |  
          評論    共 20 條 發表評論
          rubin     2007-02-11 21:32

          能否說下動態代理的原理?比如,ci2.buy(); 為什么就能執行,而ComputerProxy2 并沒有這個函數?

          lyx_2709     2007-02-12 16:09

          動態代理一定要實現這個InvocationHandle接口.接口里面有兩個方法.一個bind描述代理那個類,也就是與那個類有關系,主函數里我調用bind方法時給出Computer.也就是代理的Computer類.還有一個方法invoke就是代理與要執行的方法.

          rubin     2007-02-14 18:57

          哦,我看錯了,現在明白了,多謝!

          lyx_2709     2007-02-14 21:07

          呵呵,客氣什么.互相學習吧.

          weiqingfei     2007-02-20 09:47

          按照代理模式的定義
          代理類和被代理類都要實現統一的一個接口,
          也就是說Computer,和ComputerProxy都應該實現ComputerInterface,
          既然這樣,你的第一個實現里,廠商和代理上應該是可以隨便組合的,怎么就只適合“IBM筆記本”了?

          你為什么有搞一個動態代理呢?有什么優點兒?

          lyx_2709     2007-02-20 17:11

          對啊,IBM的本只送鼠標.如果現在SONY的本送鼠標和包,靜態的代理就實現不了了.只有改程序了.使用動態代理,我們只關注買的是什么品牌的本.送的是什么東西.

          weiqingfei     2007-02-21 08:27

          lyx_2709 寫道
          對啊,IBM的本只送鼠標.如果現在SONY的本送鼠標和包,靜態的代理就實現不了了.只有改程序了.使用動態代理,我們只關注買的是什么品牌的本.送的是什么東西.

           

          好,如果你讓你這個動態代理去賣SONY的本子,他怎么送包?你還不是要修改invoke方法么?

          動態代理的好處并不是要動態處理不同的任務,而是動態處理不同的類型,我所說的類型,指的是接口類型。
          如果說你的IBM本和sony本繼承的同樣的接口,用動態代理一點兒意義都沒有了。因為它和靜態代理一樣,只能完成一件附加任務。

          lyx_2709     2007-02-23 14:51

          嗯,也有道理,
          為其他對象提供一種代理以控制對這個對象的訪問,說白了就是,在一些情況下客戶不想或都不能直接引用一個對象,而代理對象可以在客戶和目標對象之間起到中介作用,去掉客戶不能看到的內容和服務或都增添客戶需要的額外服務.
          無論是什么代理商本是肯定的賣的,我們就要實現ComputerInterface這個接口,而不同的代理商優惠的條件不同,在這里也就是說贈的東西不同,我們代理的目的,和現時一樣,本本賣的基礎上,各個代理商送的東西不同.invoke這個方法在這里就描述了我們送的是什么東西.
          我是這樣認為的.

          weiqingfei     2007-02-23 21:23

          lyx_2709 寫道
          嗯,也有道理,
          為其他對象提供一種代理以控制對這個對象的訪問,說白了就是,在一些情況下客戶不想或都不能直接引用一個對象,而代理對象可以在客戶和目標對象之間起到中介作用,去掉客戶不能看到的內容和服務或都增添客戶需要的額外服務.
          無論是什么代理商本是肯定的賣的,我們就要實現ComputerInterface這個接口,而不同的代理商優惠的條件不同,在這里也就是說贈的東西不同,我們代理的目的,和現時一樣,本本賣的基礎上,各個代理商送的東西不同.invoke這個方法在這里就描述了我們送的是什么東西.
          我是這樣認為的.

           

          可能我們想的都一樣,只是描述的不是很清楚吧。

          動態代理和靜態代理的主要區別是,靜態代理已經知道自己要代理什么類型的東西了,而動態代理卻不知道。
          比如說,靜態代理已經明確是代理買還是賣,還是修理。

          但是動態代理不知道,它可以代理一切,只要是有可代理的東西。

          但是在代理商自己的附加動作上,兩種代理方式應該都是確定了的。
          如果一個代理商要送鼠標,那他只能送鼠標,不管他是賣什么東西。
          如果想送鼠標又要送鍵盤,那就得再找一個代理商,不管是靜態的還是動態的。

          qinysong     2007-03-24 12:58

          lyx_2709 寫道
          代理模式:為其他對象提供一種代理以控制對這個對象的訪問.說白了就是,在一些情況下客戶不想或不能直接引一個對象,而代理對象可以在客戶和目標對象之間起到中介作用.去掉客戶不能看到的內容和服務或都增添客戶需要的額外服務.
          給大家舉個比較簡單的例子:
          假如你買臺IBM的筆記本,IBM產家是不提供鼠標的.但是我們如果從代理商的手里買就有鼠標和送.
          很簡單的例子,寫幾個類來實現一下吧.
          首先設計一個購買的接口代碼如下:(ComputerInterface.java)
          package test.lyx;
          publicinterface ComputerInterface {
          publicvoid buy();
          }
          建一個電腦類實現購買的接口代碼如下:(Computer.java)
          package test.lyx;
          publicclass Computer implements ComputerInterface{
          private String pcName="IBMT60";
          privateintpcPrice=17800;
          public String getPcName() {
          returnpcName;
          }
          publicvoid setPcName(String pcName) {
          this.pcName = pcName;
          }
          publicint getPcPrice() {
          returnpcPrice;
          }
          publicvoid setPcPrice(int pcPrice) {
          this.pcPrice = pcPrice;
          }
          publicvoid buy() {
          System.out.print("獲得筆記本電腦:"+pcName+"一臺");
          }
          }
          再建設一個代理商的類:用來完成買電腦和贈送鼠標:(ComputerProxy.java)
          package test.lyx;
          publicclass ComputerProxy {
          private ComputerInterface pci;
          public ComputerInterface getPci() {
          returnpci;
          }
          publicvoid setPci(ComputerInterface pci) {
          this.pci = pci;
          }
          publicvoid buy(){
          pci.buy();
          System.out.println("贈送鼠標一個");
          }
          }
          建一個主函數測試一下吧:(TestDemo.java)
          package test.lyx;
          publicclass TestDemo {
          publicstaticvoid main(String[] args) {
          ComputerProxy c1=new ComputerProxy();
          c1.setPci(new Computer());
          c1.buy();
          }
          }
          運行結果如下:
          獲得筆記本電腦:IBMT60一臺獲得鼠標一個
          以上就是代理功能的實現,由代理商銷售筆記本,并贈送鼠標.但是這樣的程序只適合是銷售IBM筆記本.

          對于這個代理的例子,我覺得有兩個問題:

           

          第一,這個例子所表現的不是代理Proxy模式,而是裝飾器Decorator模式,Decorator模式正是這個例子所表現的為對象動態的添加一些額外的功能或職責;

          第二,無論是Proxy模式還是Decorator模式,他們有一個相同的一點是他們與被代理和被裝飾的對象具有相同的接口,以便為客戶提供透明性,而這點上面的例子沒有實現。

          對于Proxy和Decorator的比較,可以看看這篇帖子http://www.javaeye.com/topic/39053
          以上只是個人看法,共同探討

          posted on 2007-09-22 21:20 禮物 閱讀(470) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 西贡区| 南京市| 洛扎县| 都江堰市| 昌吉市| 伊川县| 乡宁县| 金乡县| 宣恩县| 岳池县| 中牟县| 阿拉善右旗| 伊金霍洛旗| 得荣县| 突泉县| 五华县| 合水县| 莆田市| 安丘市| 襄樊市| 邛崃市| 米易县| 自贡市| 新密市| 交口县| 东兴市| 海兴县| 本溪市| 井研县| 敦化市| 喀喇沁旗| 东兴市| 宁国市| 潞城市| 龙里县| 宁德市| 永和县| 盘锦市| 陆丰市| 疏勒县| 靖安县|