The NoteBook of EricKong

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

          類(lèi)適配器
          客戶的開(kāi)發(fā)人員定義了一個(gè)接口,期望用這個(gè)接口來(lái)完成整數(shù)的求和操作,接口定義如下:
           
          public interface Operation{   
                public int add(int a,int b);   

           開(kāi)發(fā)人員在了解這個(gè)接口的定義后,發(fā)現(xiàn)一個(gè)第三方類(lèi),里面有一個(gè)方法能實(shí)現(xiàn)他們期望的功能,其代碼如下:
           
          public class OtherOperation{   
                public int otherAdd(int a,int b){   
                     return a + b;   
                }   

           以上第三方類(lèi)OtherOperation的方法public int otherAdd(int a,int b)所提供的功能,完全能符合客戶的期望,所以只需要想辦法把OtherOperation的otherAdd(int a,int b)和客戶的Operation接口聯(lián)系起來(lái),讓這個(gè)第三方類(lèi)來(lái)為客戶提供他們期望的服務(wù)就行了,這樣就避免了開(kāi)發(fā)人員再度去研究類(lèi)似OtherOperation的otherAdd(int a,int b)方法的實(shí)現(xiàn)(利用已有的輪子,避免重復(fù)發(fā)明),這方法之一,就是用適配器模式:
           
          public class AdapterOperation extends OtherOperation implements Operation{   
                public int add(int a,int b){   
                     return otherAdd(a,b);   
                }   

           以上就是適配器的實(shí)現(xiàn)方法之一,類(lèi)適配器,在以上實(shí)現(xiàn)中存在著三中角色分別是:
          1:適配目標(biāo)角色:Operation。
          2:適配類(lèi)(原)角色:OtherOperation。
          3:適配器角色:AdapterOperation。
          其中適配器角色是適配器模式的核心。
          適配器的主要工作就是通過(guò)封裝現(xiàn)有的功能,使他滿足需要的接口。
          對(duì)象適配器
          我們?cè)賮?lái)看看另一種情況:
          假如客戶接口期望的功能不止一個(gè),而是多個(gè):
           
          public interface Operation{   
                public int add(int a,int b);   
                public int minus(int a,int b);   
                public int multiplied(int a,int b);   

           而能提供這些實(shí)現(xiàn)的原可能不止一個(gè):
           
          public class OtherAdd{   
                public int otherAdd(int a,int b){   
                     return a + b;   
                }   
          }   
            
          public class OtherMinus{   
                public int minus(int a,int b){   
                     return a - b;   
                }   
          }   
            
          public class OtherMultiplied{   
                public int multiplied(int a,int b){   
                     return a * b;   
                }   

           由于java是不能實(shí)現(xiàn)多繼承的,所以我們不能通過(guò)構(gòu)建一個(gè)適配器,讓他來(lái)繼承所有原以完成我們的期望,這時(shí)候怎么辦呢?只能用適配器的另一種實(shí)現(xiàn)--對(duì)象適配器:
           
          public class AdapterOperation implements Operation{   
                private OtherAdd add;   
                private OtherMinus minus;   
                private OtherMultiplied multiplied;   
            
                public void setAdd(OtherAdd add){   
                      this.add = add;   
                }   
            
                public void setMinus(OtherMinus minus){   
                      this.minus = minus;   
                }   
            
                public void setMultiplied(OtherMultiplied multiplied){   
                      this.multiplied = multiplied;   
                }   
            
                //適配加法運(yùn)算   
                public int add(int a,int b){   
                     return add.otherAdd(a,b);   
                }   
            
                //適配減法運(yùn)算   
                public int minus(int a,int b){   
                    return minus.minus(a,b);   
                }   
            
                //適配乘法運(yùn)算   
                public int multiplied(int a,int b){   
                   return multiplied.multiplied(a,b);   
                }   
          }
           
           

          上面代碼很明顯,適配器并不是通過(guò)繼承來(lái)獲取適配類(lèi)(原)的功能的,而是通過(guò)適配類(lèi)的對(duì)象來(lái)獲取的,這就解決了java不能多繼承所帶來(lái)的不便了。這也是java提倡的編程思想之一,即盡量使用聚合不要使用繼承。 還有一種情況是需要使用對(duì)象適配器的。我們來(lái)看看,單我們的客戶提供的需求并不是一個(gè)明確的接口,而是一個(gè)類(lèi),并沒(méi)有定義期望的方法,如下
           
          public class A{   
             public int add(int a,int b){   
                return a + b;   
             }   

           
          現(xiàn)在客戶要一個(gè)新類(lèi)B,要求能在保留類(lèi)A功能的情況下增加一個(gè)運(yùn)算減法的功能,并要求B能隨時(shí)替換掉A但不能對(duì)已有系統(tǒng)造成影響。這樣我們只能新建一個(gè)類(lèi)B,并讓B繼承A。
           
          public class B extends A{   
              b(){   
                super();   
              }   
            
              public int minus(int a,int b){   
                     //待實(shí)現(xiàn)的減法運(yùn)算函數(shù)..   
              }   

           
          這時(shí)候,我們發(fā)現(xiàn)類(lèi)C已經(jīng)提供了實(shí)現(xiàn)減法的函數(shù),
           
          public class C{
              public int minus(int a,int b){
                     return a - b;
              }
          }

          為了避免重復(fù)去設(shè)計(jì)該函數(shù),我們決定引入C類(lèi),通過(guò)適配C類(lèi)來(lái)達(dá)到我們的期望,但問(wèn)題是A和C都是一個(gè)具體類(lèi),我們無(wú)法讓B同時(shí)繼承這個(gè)兩個(gè)類(lèi),而B(niǎo)繼承A又是必須的,所以我們只能考慮把C給內(nèi)聚到B內(nèi)部,對(duì)象適配器又得派上用場(chǎng)了。
           
          public class B extends A{
              private C c;
              B(){
                super();
              }
              public void setMinus(C c){
                   this.c= c;
              }
              public int minus(int a,int b){
                     return c.minus(a,b);
              }
          }

          這樣,在需要A類(lèi)的地方都能用B類(lèi)來(lái)代替,同時(shí)又保證了新的功能的引入。
          更靈活的實(shí)現(xiàn)--隱藏目標(biāo)接口的抽象適配器
          做java 桌面應(yīng)用的都知道WindowListener接口,
           
          public interface WindowListener extends EventListener{
           public void windowActivated(WindowEvent e);
           public void windowClosed(WindowEvent e);
           public void windowClosing(WindowEvent e);
           public void windowDeactivated(WindowEvent e);
           public void windowDeiconified(WindowEvent e);
           public void windowIconified(WindowEvent e);
           public void windowOpened(WindowEvent e);
          }

          要實(shí)現(xiàn)這個(gè)接口,我們就必須實(shí)現(xiàn)它所定義的所有方法,但是實(shí)際上,我們很少需要同時(shí)用到所有的方法,我們要的只是其中的兩三個(gè)。為了不使我們實(shí)現(xiàn)多余的方法,
          jdk WindowListener提供了一個(gè)WindowListener的默認(rèn)實(shí)現(xiàn)類(lèi)WindowAdapter類(lèi),這是一個(gè)抽象類(lèi),
           
          public abstract class WindowAdapter implements WindowListener{
           public void windowActivated(WindowEvent e){}
           public void windowClosed(WindowEvent e){}
           public void windowClosing(WindowEvent e){}
           public void windowDeactivated(WindowEvent e){}
           public void windowDeiconified(WindowEvent e){}
           public void windowIconified(WindowEvent e){}
           public void windowOpened(WindowEvent e){}
          }

          WindowAdapter類(lèi)對(duì)WindowListener接口的所有有方法都提供了空實(shí)現(xiàn),
          有了WindowAdapter類(lèi),我們只需要去繼承WindowAdapter,然后選擇我們所關(guān)心的方法來(lái)實(shí)現(xiàn)就行了,這樣就避免了直接去實(shí)現(xiàn)WindowListener接口。

          posted on 2010-10-29 20:56 Eric_jiang 閱讀(319) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 設(shè)計(jì)模式
          主站蜘蛛池模板: 嘉善县| 汽车| 海安县| 工布江达县| 河津市| 汉川市| 思南县| 宁波市| 黄龙县| 闻喜县| 博湖县| 白玉县| 曲周县| 静乐县| 泽州县| 南昌县| 旺苍县| 琼海市| 镇平县| 武城县| 芜湖县| 卢龙县| 扎囊县| 南涧| 高台县| 广饶县| 鹿泉市| 工布江达县| 眉山市| 海宁市| 新龙县| 松阳县| 梁平县| 土默特右旗| 高唐县| 团风县| 贵定县| 隆德县| 津南区| 芜湖县| 社旗县|