国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
IAdaptable和IAdaptableFactory

1. 簡(jiǎn)介和簡(jiǎn)單的實(shí)現(xiàn)

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

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,并且實(shí)現(xiàn)了IAdaptable接口,我們想要將它轉(zhuǎn)化成Vector類型對(duì)象,于是在getAdapter方法中我們判斷傳入?yún)?shù)類型,如果是Vector類那么就新生成一個(gè)Vector對(duì)象,將ArrayList中的值全部賦給它,并返回。

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

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


ArrayList會(huì)返回Vector對(duì)象,這個(gè)對(duì)象是ArrayList的一個(gè)另外一種類型的副本。

2.一個(gè)Swing程序

讀者會(huì)問:這有什么用啊,不就簡(jiǎn)單轉(zhuǎn)化一下麼。其實(shí)說實(shí)話,從上面的代碼來看確實(shí)沒什么用,但是如果我們換一個(gè)場(chǎng)景試試。

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

看看代碼:

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);
                      }
                  });

      }




 運(yùn)行我們的代碼,會(huì)發(fā)現(xiàn)效果還可以,每當(dāng)我們選項(xiàng)改變的時(shí)候,Table就如同一個(gè)屬性欄一樣,改變著自己的內(nèi)容:


3.需求變更

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

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

無奈,我新增加了一個(gè)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);



結(jié)果還是讓人滿意的:


后來我感覺ActionListener代碼有一些凌亂,又封裝了一個(gè)Builder類,讓它創(chuàng)建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;

}


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

4.需求又變了

第二天,組長(zhǎng)告訴我,需求又變了,這會(huì)不但多增加一個(gè)“服裝”類型,Product類型屬性顯示有錯(cuò)誤,并且需要增加一個(gè)Tree,顯示當(dāng)前同種類型直接的層次結(jié)構(gòu),等等。

我聽了領(lǐng)導(dǎo)嘮叨半個(gè)小時(shí)后,打開了我剛寫的Builder類,往里面增加著我的代碼……

類圖大致如下:




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

“悲哀,真讓我替你感到悲~哀!”組長(zhǎng)操著本山的腔調(diào)這樣對(duì)我說。

是啊,多悲哀啊,一個(gè)設(shè)計(jì)上的錯(cuò)誤讓我的代碼無法適應(yīng)需求的變化。



好了,讓我們回到IAdaptable上。

通過上面的例子,我看可以發(fā)現(xiàn)這么一個(gè)情況:同樣一個(gè)對(duì)象,在程序里面往往有許多不同的顯示方式(不僅僅是在UI顯示,在其他一些代碼里,需要轉(zhuǎn)化成另外類型或者數(shù)據(jù)結(jié)構(gòu))。

如果我用IAdapteable的思想來實(shí)現(xiàn)剛才的Swing屬性顯示,會(huì)怎么樣呢?

重新寫一遍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實(shí)現(xiàn)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
;
 }
}

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

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



這樣一來,我們的Swing程序不僅功能能夠?qū)崿F(xiàn),而且UI部分代碼和業(yè)務(wù)模型代碼之間的耦合性減小了。

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

現(xiàn)在我可以對(duì)組長(zhǎng)說:讓需求變化來得更猛烈些吧!


5.模型代碼無法修改

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

IAdapterFactory就是為這種情況準(zhǔn)備的。

先看看IAdapterFactory:

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


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

在Eclipse中IAdapterFactory并不是單獨(dú)存在的,而是有一個(gè)IAdapterManager對(duì)它進(jìn)行維護(hù)的:

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


現(xiàn)在讓我們這樣來修改剛才的Swing程序:

假設(shè)Product類型是第三方提供的jar包,我們已經(jīng)無法修改它的代碼了,那我們就需要用到IAdapableFactory的擴(kuò)展方法。請(qǐng)看下面的代碼

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;
 }
}


有了這兩個(gè)實(shí)現(xiàn)類后,我們?cè)偃バ薷囊幌翧ctionListener中的代碼:

         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);


好了,只要我們?cè)谶m當(dāng)?shù)牡胤剑瑢AdaptableFactory注冊(cè)進(jìn)IAdaptaerManager,那我們對(duì)無法修改代碼的業(yè)務(wù)模型也能進(jìn)行接口的擴(kuò)展了。

6.結(jié)束語(yǔ)

在Eclipse中,IAdaptable的應(yīng)用非常廣泛,而且如果實(shí)現(xiàn)了IAdaptable接口的類被成為Platform Object,可見IAdaptable在Eclipse框架中的分量。本人的知識(shí)有限,如果有遺漏或者錯(cuò)誤的地方,還請(qǐng)各位讀者指出。

轉(zhuǎn)貼網(wǎng)址:http://www.blogjava.net/reloadcn/archive/2006/10/09/iadaptable.html
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
[翻譯]IAdaptable是什么? - 八進(jìn)制
讓界面更加絢麗 Java SE 6.0四種新功能
Eclipse中類型擴(kuò)展機(jī)制分析
java從入門到精髓 - Swing表格JTable利用tableModel添加行修改行刪除行
java 反射機(jī)制
Java類型轉(zhuǎn)換器
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服