<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    呆羊在曬太陽  
    公告
    • Y:哦,是你呀。
      X:我現在正在忙。
      Y:忙什么?
      X:呵呵,今天出太陽了,我把錢搬出來曬一曬。
      ***********************
      abc
      小叉
      很高興能結識大家!
      ***********************
    日歷
    <2006年1月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234
    統計
    • 隨筆 - 164
    • 文章 - 2
    • 評論 - 196
    • 引用 - 0

    導航

    常用鏈接

    留言簿(7)

    隨筆分類(158)

    文章分類(2)

    相冊

    log

    搜索

    •  

    積分與排名

    • 積分 - 70657
    • 排名 - 781

    最新評論

    閱讀排行榜

     

    1. 簡介和簡單的實現

    IAdapteable實際上在Eclipse早期版本中不叫這個名字,它原來的名字叫做IExtensible,顧名思義就是可以擴展的意思,后來為了更能突出是由一個類配適到一個接口這么一種機制,所以改名為IAdaptable。
    這個接口有什么用呢,其實說白了,就是提供一個類型的轉換機制。比如下面這段代碼:

    Class IAdaptable  
    public interface
     IAdaptable  {
     
    public
     Object getAdapter(Class clazz);
    }

    Class ListAdapter
    public class ListAdapter extends ArrayList implements
     IAdaptable {
     
    public
     Object getAdapter(Class clazz) {
      
    if(clazz == Vector.class
    ){
       Vector v 
    = new Vector(this
    .size());
       v.addAll(
    this
    );
       
    return
     v;
      }
      
    return null
    ;
     }
    }


    ListAdapter類繼承了ArrayList,并且實現了IAdaptable接口,我們 想要將它轉化成Vector類型對象,于是在getAdapter方法中我們判斷傳入參數類型,如果是Vector類那么就新生成一個Vector對象,將ArrayList中的值全部賦給它,并返回。

    這樣,我們就可以寫出以下代碼:

    ListAdapter list = new ListAdapter();
      Vector v 
    = (Vector) list.getAdapter(Vector.class);


    ArrayList會返回Vector對象,這個對象是ArrayList的一個另外一種類型的副本。

    2.一個Swing程序

    讀者會問:這有什么用啊,不就簡單轉化一下麼。其實說實話,從上面的代碼來看確實沒什么用,但是如果我們換一個場景試試。

    寫這么一個Swing程序:有一個對話框,其中它有一個ComboBox和一個Table,ComboBox中存放的是一個名為Person類型的對象,當ComboBox的選項發生改變的時候,就在Table上顯示它的屬性,我們假設這個Swing程序已經在某個項目中開始實施,并且其界面布局不易更改。

    看看代碼:

    Class person
    public class
     Person {
     
    private String name = "name"
    ;
     
    private String age = "23"
    ;
     
    private String sex = "male"
    ;
     
     
    public
     Person(String name){
      
    this
    .setName(name);
     }
     
     
    public
     String getName() {
      
    return
     name;
     }
     
     
    public void
     setName(String name) {
      
    this.name =
     name;
     }
     ……
    }

    UI類的部分代碼:

    {
           table 
    = new
     JTable();
           
    this
    .getContentPane().add(table);
           table.setBounds(
    2182171248
    );
          }
          {
           ComboBoxModel jComboBox1Model 
    = new
     DefaultComboBoxModel(
            
    new Object[] { new Person("rEloaD"), new Person("b"
    ) });
           comboBox 
    = new
     JComboBox();
           
    this
    .getContentPane().add(comboBox);
           comboBox.setModel(jComboBox1Model); 
           comboBox.addActionListener(
    new
     ActionListener(){
                     
    public void
     actionPerformed(ActionEvent e){
                         JComboBox comboBox 
    =
    (JComboBox)e.getSource();
                         Person p 
    =
     (Person)comboBox.getSelectedItem();
                         TableModel jTable1Model 
    = new
     DefaultTableModel(
                                         
    new String[][] { { "Name"
    , p.getName() },
                                                           { 
    "Sex"
    , p.getSex() },
                                                          { 
    "Age"
    , p.getAge() }},
                                         
    new String[] { "Column 1""Column 2"
     });
                         table.setModel(jTable1Model);
                          }
                      });

          }


    ClassDiagram2.JPG



     運行我們的代碼,會發現效果還可以,每當我們選項改變的時候,Table就如同一個屬性欄一樣,改變著自己的內容:

    jframe.JPG



    3.需求變更

    OK,問題來了。我寫完這段代碼后,組長告訴我,現在我們有一個新的需求,就是Combox中不僅僅有Person類型存在,而且還有一些貨物(Product)類型,也就是說,我的table顯示屬性不能光針對Person這個類型了,還需要顯示Product的屬性。

    我心里罵了句:早TMD干嘛了,都快交活兒了才告訴我。

    無奈,我新增加了一個Product類型,然后更改了ActionListener中的部分代碼:

    JComboBox comboBox =(JComboBox)e.getSource();
     Object obj 
    =
     comboBox.getSelectedItem();
     TableModel jTable1Model 
    = null
    ;
      
    if(obj instanceof
     Person){
          jTable1Model 
    = new
     DefaultTableModel(
                              
    new String[][] { { "Name"
    , ((Person)obj).getName() },
                                               { 
    "Sex"
    , ((Person)obj).getSex() },
                                                { 
    "Age"
    , ((Person)obj).getAge() }},
                               
    new String[] { "Column 1""Column 2"
     });
      }
      
    if(obj instanceof
     Product){
          jTable1Model 
    = new
     DefaultTableModel(
                            
    new String[][] { { "Name"
    , ((Product)obj).name },
                                              { 
    "price"
    , ((Product)obj).price },
                                              { 
    "quantity"
    , ((Product)obj).quantity }},
                             
    new String[] { "Column 1""Column 2"
     });

      }
      table.setModel(jTable1Model);


    ClassDiagram3.JPG


    結果還是讓人滿意的:

    jframe1.JPG


    后來我感覺ActionListener代碼有一些凌亂,又封裝了一個Builder類,讓它創建TableModel:

    public static TableModel modelBuilder(Object obj){
    TableModel jTable1Model = null;
      
    if(obj instanceof
     Person){
              jTable1Model 
    = new
     DefaultTableModel(
                 
    new String[][] { { "Name"
    , ((Person)obj).getName() },
                   { 
    "Sex"
    , ((Person)obj).getSex() },
                   { 
    "Age"
    , ((Person)obj).getAge() }},
                 
    new String[] { "Column 1""Column 2"
     });
                              }
                              
    if(obj instanceof
     Product){
                                jTable1Model 
    = new
     DefaultTableModel(
                   
    new String[][] { { "Name"
    , ((Product)obj).name },
                     { 
    "price"
    , ((Product)obj).price },
                     { 
    "quantity"
    , ((Product)obj).quantity }},
                   
    new String[] { "Column 1""Column 2"
     });

      }
    return
     jTable1Model;

    }


    我對自己的代碼還算滿意,至少目前能用了。

    4.需求又變了

    第二天,組長告訴我,需求又變了,這會不但多增加一個“服裝”類型,Product類型屬性顯示有錯誤,并且需要增加一個Tree,顯示當前同種類型直接的層次結構,等等。

    我聽了領導嘮叨半個小時后,打開了我剛寫的Builder類,往里面增加著我的代碼……

    類圖大致如下:

    ClassDiagram4.JPG


    程序經過修改后,好不容易又符合要求了,情況又發生了變化,組長需要我繼續修改。我無奈地看著組長,組長也無奈地看著我那用if-else堆成的代碼……

    “悲哀,真讓我替你感到悲~哀!”組長操著本山的腔調這樣對我說。

    是啊,多悲哀啊,一個設計上的錯誤讓我的代碼無法適應需求的變化。

    好了,讓我們回到IAdaptable上。

    通過上面的例子,我看可以發現這么一個情況:同樣一個對象,在程序里面往往有許多不同的顯示方式(不僅僅是在UI顯示,在其他一些代碼里,需要轉化成另外類型或者數據結構)。

    如果我用IAdapteable的思想來實現剛才的Swing屬性顯示,會怎么樣呢?

    重新寫一遍ActionListener中的代碼:

    JComboBox comboBox =(JComboBox)e.getSource();
    Object obj 
    =
     comboBox.getSelectedItem();
    TableModel jTable1Model 
    = null
    ;
    if(obj instanceof
     IAdaptable){
           jTable1Model 
    = (TableModel) ((IAdaptable)obj).getAdapter(TableModel.class
    );
    }
    table.setModel(jTable1Model);

    然后分別讓Person和Product實現IAdaptable接口:

    Class Person:
    public class Person implements
     IAdaptable{
       …..
       
    public
     Object getAdapter(Class clazz) {
      
    if(clazz == TableModel.class
    ){
        
    return new
     DefaultTableModel(
          
    new String[][] { { "Name"
    , getName() },
            { 
    "Sex"
    , getSex() },
            { 
    "Age"
    , getAge() }},
          
    new String[] { "Column 1""Column 2"
     });
      }
      
    return null
    ;
     }
    }

    Class Product
    public class Product implements
     IAdaptable{
     ……
        
    public
     Object getAdapter(Class clazz) {
      
    if(clazz == TableModel.class
    ){
        
    return new
     DefaultTableModel(
          
    new String[][] { { "Name"
    , getName() },
            { 
    "Sex"
    , getSex() },
            { 
    "Age"
    , getAge() }},
          
    new String[] { "Column 1""Column 2"
     });
      }
      
    return null
    ;
     }
    }

    其實我們的代碼量并沒有任何的改變,前后都是一樣的。

    但是我們將Table需要顯示的模型(TableModel),現在是作為擴展類接口抽取了出來,而那些需要在Table上顯示自己屬性的業務模型(Person,Product)實現了IAdaptable接口,將顯示模型(TableModel)作為了自己的擴展接口類型給予實例返回,并且UI代碼中,Table和業務模型之間形成一種契約:凡是實現了IAdaptable的接口才可以獲得在該Table上顯示的資格,并且Table從IAdaptable的getAdapter方法獲得顯示模型:

    ClassDiagram5.JPG



    這樣一來,我們的Swing程序不僅功能能夠實現,而且UI部分代碼和業務模型代碼之間的耦合性減小了。

    而且,如果需求發生變化,比如像剛才提到那樣“需要增加一個Tree,顯示當前同種類型直接的層次結構”,那我們就在getAdaper方法中返回一個TreeModel的副本,然后在UI中增加一個Tree,讓它像Table一樣,從IAdaptable接口中取出我們的TreeModel即可——UI擴展也變得容易起來。

    現在我可以對組長說:讓需求變化來得更猛烈些吧!

    5.模型代碼無法修改

    有這樣一個問題:如果我們的模型已經存在,而且代碼已經無法修改了怎么辦?

    IAdapterFactory就是為這種情況準備的。

    先看看IAdapterFactory:

    public interface IAdaptableFactory {
     
    public
     Object getAdapter(Object adapter,Class clazz);
    }


    這里面的方法和IAdaptable差不多,只是多了一個參數,這個參數就是需要我們返回Adapter接口的對象。

    在Eclipse中IAdapterFactory并不是單獨存在的,而是有一個IAdapterManager對它進行維護的:

    public interface IAdaptableManager {
     
    public
     Object getAdapter(Object adapter,Class clazz);
     
    public boolean
     registerAdapters (Class clazz,IAdaptableFactory factory);
    }


    現在讓我們這樣來修改剛才的Swing程序:

    假設Product類型是第三方提供的jar包,我們已經無法修改它的代碼了,那我們就需要用到IAdapableFactory的擴展方法。請看下面的代碼

    Class AdaptableFactoryImpl
    public class AdaptableFactoryImpl implements
     IAdaptableFactory {
     
    public
     Object getAdapter(Object adapter, Class clazz) {
      
    if(adapter instanceof
     Product){
       
    if(clazz ==TableModel.class
    ){
        
    return new
     DefaultTableModel(
          
    new String[][] { { "Name"
    ,((Product)adapter).name },
            { 
    "price"
    , ((Product)adapter).price },
            { 
    "quantity"
    , ((Product)adapter).quantity }},
          
    new String[] { "Column 1""Column 2"
     });
       }
      }
      
    return null
    ;
     }
     
    public
     Class[] getAdapterList() {
      
    return new Class[]{TableModel.class
    };
     }
    }

    Class AdapterManagerImpl:
    public class AdapterManagerImpl implements
     IAdaptableManager {
     
    private static AdapterManagerImpl instance = null
    ;
     
    private Hashtable table = new
     Hashtable();
     
     
    private
     AdapterManagerImpl(){}
     
     
    public
     Object getAdapter(Object adapter, Class clazz) {
      Object factory 
    =
     table.get(adapter.getClass());
      
    if(factory != null
    ){
       
    return
     ((IAdaptableFactory)factory).getAdapter(adapter,clazz);
      }
      
    return null
    ;
     }

     
    public boolean
     registerFacotry(Class clazz, IAdaptableFactory factory) {
      
    try
    {
       table.put(clazz,factory);
       
    return true
    ;
      }
    catch
    (Exception e){
       
    return false
    ;
      }
     }
     
    public synchronized static
     AdapterManagerImpl getInstance() {
      
    if(instance == null) instance = new
     AdapterManagerImpl();
      
    return
     instance;
     }
    }


    有了這兩個實現類后,我們再去修改一下ActionListener中的代碼:

             JComboBox comboBox = (JComboBox) e.getSource();
             Object obj 
    =
     comboBox.getSelectedItem();
             TableModel jTable1Model 
    = null
    ;
             
    if (obj instanceof
     IAdaptable) {
              jTable1Model 
    =
     (TableModel) ((IAdaptable) obj)
                .getAdapter(TableModel.
    class
    );
             } 
    else
     {
              jTable1Model 
    =
     (TableModel) AdapterManagerImpl
                .getInstance().getAdapter(obj,
                  TableModel.
    class
    );
             }
             table.setModel(jTable1Model);


    好了,只要我們在適當的地方,將IAdaptableFactory注冊進IAdaptaerManager,那我們對無法修改代碼的業務模型也能進行接口的擴展了。

    6.結束語

    在Eclipse中,IAdaptable的應用非常廣泛,而且如果實現了IAdaptable接口的類被成為Platform Object,可見IAdaptable在Eclipse框架中的分量。本人的知識有限,如果有遺漏或者錯誤的地方,還請各位讀者指出。

    classdiagram.JPG

    posted on 2006-01-10 16:56 小叉 閱讀(232) 評論(0)  編輯  收藏 所屬分類: 轉載
     
    Copyright © 小叉 Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 日韩视频在线免费| 免费无码又黄又爽又刺激| 亚洲福利中文字幕在线网址| 亚洲 暴爽 AV人人爽日日碰| 欧洲乱码伦视频免费| 亚洲日韩图片专区第1页| 免费成人在线电影| 亚洲视频欧洲视频| 一二三四免费观看在线视频中文版| 亚洲码一区二区三区| 国产免费久久精品99re丫y| 亚洲jjzzjjzz在线播放| 成人免费福利电影| 免费看一级毛片在线观看精品视频| 亚洲?v无码国产在丝袜线观看 | 亚洲伦理中文字幕| 成年女人喷潮毛片免费播放| 亚洲精品乱码久久久久蜜桃 | 久久久久久国产a免费观看黄色大片 | 2021免费日韩视频网| 亚洲综合色7777情网站777| 成年人免费网站在线观看| 狠狠热精品免费观看| 亚洲乱码一区二区三区在线观看 | 亚洲av无码成人影院一区| 亚洲日本中文字幕天堂网| 一级毛片全部免费播放| 国产亚洲精aa在线看| 久久久久亚洲精品中文字幕| 一级毛片免费毛片一级毛片免费 | 亚洲国产人成在线观看69网站| 美女内射毛片在线看免费人动物| 亚洲日韩一区二区一无码| 亚洲一区二区视频在线观看| 小草在线看片免费人成视久网| 亚洲乱码在线观看| 亚洲午夜福利AV一区二区无码| 国拍在线精品视频免费观看 | 全免费a级毛片免费看无码| 三级网站免费观看| 亚洲国产视频网站|