第二章 JavaBeans 和屬性
Tapestry框架基于JavaBeans 和JavaBeans 屬性的使用。這個章節(jié)將對這些概念作簡短的回顧。更加深入的討論是可參閱Java Tutorial。
2.1 JavaBeans
當Java對象確切的類型是未知的時候,JavaBeans 框架是操縱Java對象的一個方式。這種當Java對象確切的類型未知時,卻能使他們一起工作的能力, 是非常強有力的。這體現了Java作為一種高度動態(tài)語言的靈活性,這樣的例子在底層語言, 譬如C++ 中是不可能的。
許多基于組件的框架是以JavaBeans 框架為基礎,包括Java 的AWT 和Swing 的GUI庫, 還有Tapestry。 想法是這樣的, 遵照幾種命名規(guī)則和編碼習慣, 將新類"插入"一個框架中是可能的, 當框架被創(chuàng)建時, 這些類甚至還沒寫。按Tapestry術語的說法, 這被用來允許創(chuàng)建新的Tapestry組件。
任一個Java 對象可以作為JavaBean運作; 它只是必須遵循某些命名慣例(在下個部分討論)。對于框架需要在何處創(chuàng)建一個類的新實例的情況,譬如,當Tapestry創(chuàng)建組件的一個新實例時, Java 類必須實現一個公共的, 無參量的構造器(它也可以實現另外的構造器)。JavaReflection API 允許Tapestry訪問一個類的方法、屬性和構造器。
2.2 JavaBeans 屬性
對于Tapestry, JavaBeans的中心概念為屬性。JavaBeans框架允許Tapestry把任一個對象作為若干已命名屬性的一個集合來對待。Tapestry頻繁地從這些已命名屬性中讀取值,并且偶爾地值將寫入這些已命名屬性中。這里指的屬性(property)不同于性質(attribute)... 雖然, 經常,每個屬性(property)是由一個性質(attribute)支持。對于Tapestry, 和Reflection API,屬性是對象中一套公共的方法。訪問屬性涉及調用這些方法當中的一個。
例子2.1 JavaBeans getter方法
public type getName()
{
...
}
例子2.2 JavaBeans setter方法
public void setName(type value)
{
...
}
屬性可以是只讀或只寫的 (也就是說,它也許實現二個方法當中的一個)。類型可以是標量型(布爾, 整型, 等) 或任何Java 類。
注意命名; 屬性名稱的第一字母在get或set后面是大寫的。JavaBeans屬性對于方法名稱和屬性名稱是大小寫敏感的。當名稱是只取首字母的縮寫詞時,一種特殊情況存在;這是通過二個或更多的大寫字母(以后得到或設置)來標識; 在這種情況下, 屬性名稱沒有第一字母來轉換成小寫。
作為一種特殊情況, 一個布爾屬性可以為getter方法使用一個別名:
例子2.3。JavaBeans getter方法(布爾)
public boolean isName()
{
...
}
雖然正常實現是得到或設置實例變量, 但是更加復雜的選擇是可能的。一個方式是延遲求值, 即, 昂貴的演算被推遲直到實際值是需要的時候,
例如: 例子2.4。JavaBeans 屬性的延遲求值
public List userNames = null;
/**
* Returns a List of user names obtained from the database.
*
**/
public List getUserNames()
{
if (userNames == null)
userNames = fetchUserNamesFromDatabase();
return userNames;
}
這里,方法第一次被調用時, 昂貴的數據庫“取”指令發(fā)生。值從數據庫返回,然后被存于緩存中以備最新調用。另一種普遍的樣式是綜合的屬性。這里, 根本沒有真正的性質(attribute), 值總在進行中計算。其一個頻繁用途是避免在遭遇空指針時出錯。
例子2.5。綜合的JavaBeans 屬性
/**
* Returns the name of the company‘s account representative, if
* if the company has one, or null otherwise.
*
**/
public String getAccountRepName()
{
AccountRep rep = company.getAccountRep();
if (rep == null)
return null;
return rep.getName();
}
這個例子創(chuàng)建一個綜合屬性, accountRepName 。