Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學(xué);靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評(píng)論 :: 0 Trackbacks
          關(guān)鍵字: 設(shè)計(jì)模式       

          代理模式:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問.說白了就是,在一些情況下客戶不想或不能直接引一個(gè)對(duì)象,而代理對(duì)象可以在客戶和目標(biāo)對(duì)象之間起到中介作用.去掉客戶不能看到的內(nèi)容和服務(wù)或都增添客戶需要的額外服務(wù).
          給大家舉個(gè)比較簡單的例子:
          假如你買臺(tái)IBM的筆記本,IBM產(chǎn)家是不提供鼠標(biāo)的.但是我們?nèi)绻麖拇砩痰氖掷镔I就有鼠標(biāo)和送.
          很簡單的例子,寫幾個(gè)類來實(shí)現(xiàn)一下吧.
          首先設(shè)計(jì)一個(gè)購買的接口代碼如下:(ComputerInterface.java)
          package test.lyx;
          publicinterface ComputerInterface {
          publicvoid buy();
          }
          建一個(gè)電腦類實(shí)現(xiàn)購買的接口代碼如下:(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+"一臺(tái)");
          }
          }
          再建設(shè)一個(gè)代理商的類:用來完成買電腦和贈(zèng)送鼠標(biāo):(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("贈(zèng)送鼠標(biāo)一個(gè)");
          }
          }
          建一個(gè)主函數(shù)測試一下吧:(TestDemo.java)
          package test.lyx;
          publicclass TestDemo {
          publicstaticvoid main(String[] args) {
          ComputerProxy c1=new ComputerProxy();
          c1.setPci(new Computer());
          c1.buy();
          }
          }
          運(yùn)行結(jié)果如下:
          獲得筆記本電腦:IBMT60一臺(tái)獲得鼠標(biāo)一個(gè)
          以上就是代理功能的實(shí)現(xiàn),由代理商銷售筆記本,并贈(zèng)送鼠標(biāo).但是這樣的程序只適合是銷售IBM筆記本.那么如果要是其它品牌呢.所以我們來更改一個(gè)代理類.來實(shí)現(xiàn)動(dòng)態(tài)的代理.
          建立一個(gè)類代碼如下:(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;
          //描述是誰的代理,也就是與那個(gè)類有關(guān)系
          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("贈(zèng)送鼠標(biāo)一個(gè)!");
          Object result=method.invoke(delegate, args);
          return result;
          }
          }
          然后在主函數(shù)中加上:
          ComputerProxy2 c2=new ComputerProxy2();
          ComputerInterface ci2=(ComputerInterface)c2.bind(new Computer());
          ci2.buy();
          就可以實(shí)現(xiàn)動(dòng)態(tài)代理了.
          [b][/b]

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

          能否說下動(dòng)態(tài)代理的原理?比如,ci2.buy(); 為什么就能執(zhí)行,而ComputerProxy2 并沒有這個(gè)函數(shù)?

          lyx_2709     2007-02-12 16:09

          動(dòng)態(tài)代理一定要實(shí)現(xiàn)這個(gè)InvocationHandle接口.接口里面有兩個(gè)方法.一個(gè)bind描述代理那個(gè)類,也就是與那個(gè)類有關(guān)系,主函數(shù)里我調(diào)用bind方法時(shí)給出Computer.也就是代理的Computer類.還有一個(gè)方法invoke就是代理與要執(zhí)行的方法.

          rubin     2007-02-14 18:57

          哦,我看錯(cuò)了,現(xiàn)在明白了,多謝!

          lyx_2709     2007-02-14 21:07

          呵呵,客氣什么.互相學(xué)習(xí)吧.

          weiqingfei     2007-02-20 09:47

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

          你為什么有搞一個(gè)動(dòng)態(tài)代理呢?有什么優(yōu)點(diǎn)兒?

          lyx_2709     2007-02-20 17:11

          對(duì)啊,IBM的本只送鼠標(biāo).如果現(xiàn)在SONY的本送鼠標(biāo)和包,靜態(tài)的代理就實(shí)現(xiàn)不了了.只有改程序了.使用動(dòng)態(tài)代理,我們只關(guān)注買的是什么品牌的本.送的是什么東西.

          weiqingfei     2007-02-21 08:27

          lyx_2709 寫道
          對(duì)啊,IBM的本只送鼠標(biāo).如果現(xiàn)在SONY的本送鼠標(biāo)和包,靜態(tài)的代理就實(shí)現(xiàn)不了了.只有改程序了.使用動(dòng)態(tài)代理,我們只關(guān)注買的是什么品牌的本.送的是什么東西.

           

          好,如果你讓你這個(gè)動(dòng)態(tài)代理去賣SONY的本子,他怎么送包?你還不是要修改invoke方法么?

          動(dòng)態(tài)代理的好處并不是要?jiǎng)討B(tài)處理不同的任務(wù),而是動(dòng)態(tài)處理不同的類型,我所說的類型,指的是接口類型。
          如果說你的IBM本和sony本繼承的同樣的接口,用動(dòng)態(tài)代理一點(diǎn)兒意義都沒有了。因?yàn)樗挽o態(tài)代理一樣,只能完成一件附加任務(wù)。

          lyx_2709     2007-02-23 14:51

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

          weiqingfei     2007-02-23 21:23

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

           

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

          動(dòng)態(tài)代理和靜態(tài)代理的主要區(qū)別是,靜態(tài)代理已經(jīng)知道自己要代理什么類型的東西了,而動(dòng)態(tài)代理卻不知道。
          比如說,靜態(tài)代理已經(jīng)明確是代理買還是賣,還是修理。

          但是動(dòng)態(tài)代理不知道,它可以代理一切,只要是有可代理的東西。

          但是在代理商自己的附加動(dòng)作上,兩種代理方式應(yīng)該都是確定了的。
          如果一個(gè)代理商要送鼠標(biāo),那他只能送鼠標(biāo),不管他是賣什么東西。
          如果想送鼠標(biāo)又要送鍵盤,那就得再找一個(gè)代理商,不管是靜態(tài)的還是動(dòng)態(tài)的。

          qinysong     2007-03-24 12:58

          lyx_2709 寫道
          代理模式:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問.說白了就是,在一些情況下客戶不想或不能直接引一個(gè)對(duì)象,而代理對(duì)象可以在客戶和目標(biāo)對(duì)象之間起到中介作用.去掉客戶不能看到的內(nèi)容和服務(wù)或都增添客戶需要的額外服務(wù).
          給大家舉個(gè)比較簡單的例子:
          假如你買臺(tái)IBM的筆記本,IBM產(chǎn)家是不提供鼠標(biāo)的.但是我們?nèi)绻麖拇砩痰氖掷镔I就有鼠標(biāo)和送.
          很簡單的例子,寫幾個(gè)類來實(shí)現(xiàn)一下吧.
          首先設(shè)計(jì)一個(gè)購買的接口代碼如下:(ComputerInterface.java)
          package test.lyx;
          publicinterface ComputerInterface {
          publicvoid buy();
          }
          建一個(gè)電腦類實(shí)現(xiàn)購買的接口代碼如下:(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+"一臺(tái)");
          }
          }
          再建設(shè)一個(gè)代理商的類:用來完成買電腦和贈(zèng)送鼠標(biāo):(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("贈(zèng)送鼠標(biāo)一個(gè)");
          }
          }
          建一個(gè)主函數(shù)測試一下吧:(TestDemo.java)
          package test.lyx;
          publicclass TestDemo {
          publicstaticvoid main(String[] args) {
          ComputerProxy c1=new ComputerProxy();
          c1.setPci(new Computer());
          c1.buy();
          }
          }
          運(yùn)行結(jié)果如下:
          獲得筆記本電腦:IBMT60一臺(tái)獲得鼠標(biāo)一個(gè)
          以上就是代理功能的實(shí)現(xiàn),由代理商銷售筆記本,并贈(zèng)送鼠標(biāo).但是這樣的程序只適合是銷售IBM筆記本.

          對(duì)于這個(gè)代理的例子,我覺得有兩個(gè)問題:

           

          第一,這個(gè)例子所表現(xiàn)的不是代理Proxy模式,而是裝飾器Decorator模式,Decorator模式正是這個(gè)例子所表現(xiàn)的為對(duì)象動(dòng)態(tài)的添加一些額外的功能或職責(zé);

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

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

          posted on 2007-09-22 21:20 禮物 閱讀(470) 評(píng)論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 邓州市| 林州市| 贡嘎县| 罗田县| 航空| 建始县| 泉州市| 贵德县| 陆河县| 孙吴县| 霞浦县| 建始县| 紫金县| 竹北市| 冀州市| 珠海市| 岑巩县| 济源市| 德州市| 定襄县| 万荣县| 黔南| 阳春市| 余江县| 神池县| 积石山| 万山特区| 湖北省| 鄂托克旗| 赫章县| 乾安县| 平果县| 扎兰屯市| 慈溪市| 屯昌县| 班戈县| 抚顺市| 汝阳县| 神农架林区| 枣阳市| 宣恩县|