JavaBean 的屬性與一般Java 程序中所指的屬性,或者說與所有面向對象的程序設計語言中對象的屬性是一個概念,在程序中的具體體現就是類中的變量。在JavaBean 的設計中,按照屬性的不同作用又細分爲四類:
- 單值屬性
- 索引屬性
- 關聯屬性
- 限制屬性
一、 單值屬性
它表示一個伴隨有一對get/set 方法的變量。屬性名與和該屬性相關的get/set 方法名對應。例如:如果有setX 和getX 方法,則暗指有一個名爲"X" 的屬性。如果有一個方法名爲isX ,則通常暗指"X" 是一個布爾屬性(即X 的值爲true 或false )。
二、 索引屬性
它 表示一個數組值。使用與該屬性對應的set/get 方法可取得數組中的成員數據值(需要有一個整數 索引參數 )或者一次設置或取得整個數組的值。 索引屬性的設計模式如下:
訪問整個索引屬性 數組的方法
public <propertyType>[]get();
public void set<propertyName>([]value);
訪問整個索引屬性 中的單個值的方法
public <propertyType> get(int index);
public void set<propertyName>(int index,int value);
三、 關聯屬性
關聯屬性,也稱之爲束縛屬性(Bound ), 它是 指當該種屬性的值發生變化時,要通知其它的對象。每次的屬性值改變時,這種屬性就點火一個PropertyChange 事件。事件中封裝了屬性名、屬性的原值、屬性變化後的新值。這種事件是傳遞到其它的Bean ,至於接收事件的Bean 應做什麼動作由其自己定義。
包含 關聯 屬性的Bean 必須具有以下的功能:
1 )允許事件監聽器註冊和註銷與其有關的屬性修改事件;
2 )當修改一個 關聯 屬性時,可以在相關的監聽器上觸發屬性修改事件。
在java.beans 包中提供有PropertyChangeSupport 類,利用它創建出PropertyChangeSupport 類的對象,從而可以用於管理註冊的監聽器列表和屬性修改事件通知的發送。
關聯屬性Bean的實現:
1、 產生變化的源需要增加 PropertyChangeSupport 的實例,傳入 this 作爲參數。
2、 在屬性變化處進行點火。
3、 增加 addListener(),removeListener() 的方法
Listener 類操作的要點:
1、 繼承 PropertyChangeListener 接口,實現 void propertyChange(PropertyChangeEvent e) 方法。
2、 創建Bean 實例。因爲要監聽 source ,所以 source 類的實例必須在 Listener 類中定義。
3、 調用 Bean 實例方法 addPropertyChangeListener(this) ,將 Listener 類加入成爲監聽者。
四、限制屬性
限制屬性( constrained )是指當這個屬性的值要發生變化時,與這個屬性已建立了某種連接的其它外部Java 對象可否決該屬性值的改變(限制 屬性的監聽者通過拋出PropertyVetoException 來阻止該屬性值的改變);當然Bean 本身也可以否決該Bean 屬性值的改變。
注意:
限制屬性實際上是一種特殊的關聯 屬性,只是它的值的變化可以被監聽者否決掉。
一個 限制 屬性有兩種監聽者:屬性變化監聽者和否決屬性改變的監聽者。否決屬性改變的監聽者在自己的對象代碼中有相應的控制語句,在監聽到有 限制 屬性要發生變化時,在控制語句中判斷是否應否決這個屬性值的改變。
總之,某個 Bean 的
限制 屬性值可否改變取決於其它的Bean 或者是其它外部Java 對象是否允許這種改變。允許與否的條件由其它的Bean 或Java 對象在自己的類中進行定義。
注意:
由於限制屬性使用了錯誤處理,編程的時候要特別注意異常的處理方式。
- package bean;
- import java.beans.PropertyChangeListener;
- import java.beans.PropertyChangeSupport;
- import java.beans.PropertyVetoException;
- import java.beans.VetoableChangeListener;
- import java.beans.VetoableChangeSupport;
- /*
- * Bean類似觀察者模式裏的主題角色或者是被觀察者角色(Observable)
- */
- public class SomeBean {
- protected PropertyChangeSupport propertySupport; //屬性改變通知支持
- protected VetoableChangeSupport vetoableChangeSupport; //反對屬性改變支持
- private String changableValue;
- public SomeBean() {
- //這裏添加支持與像使用observer模式的實現接有口異曲同工之效
- propertySupport = new PropertyChangeSupport(this);//使本對象有屬性改變通知監聽器的能力
- vetoableChangeSupport = new VetoableChangeSupport(this);//使監聽器有反對本對象屬性改變的能力
- }
- public void setChangableValue(String newValue) throws PropertyVetoException {
- //如果值發生了修改
- if (!newValue.equals(changableValue)) {
- String oldValue = changableValue;
- //這個一定要在前調用,如果監聽器拒絕會拋出異常
- vetoableChangeSupport
- .fireVetoableChange("changableValue", oldValue, newValue);
- //如果未拒絕,則修改Bean屬性
- changableValue = newValue;
- //這個在後調用,屬性修改後通知監聽器
- propertySupport.firePropertyChange("changableValue", oldValue, newValue);
- //如果兩個監聽器的次序調過來,你想想會有什麼問題?你期待的效果沒有達到哦~~~~~~~~~~~~~~~
- }
- }
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- propertySupport.addPropertyChangeListener(listener);
- }
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- propertySupport.removePropertyChangeListener(listener);
- }
- public void addVetoableChangeListener(VetoableChangeListener listener) {
- vetoableChangeSupport.addVetoableChangeListener(listener);
- }
- public void removeVetoableChangeListener(VetoableChangeListener listener) {
- vetoableChangeSupport.removeVetoableChangeListener(listener);
- }
- public String getChangableValue() {
- return changableValue;
- }
- }
- package bean;
- import java.beans.PropertyChangeEvent;
- import java.beans.PropertyChangeListener;
- import java.beans.PropertyVetoException;
- import java.beans.VetoableChangeListener;
- /*
- * 監聽器,用來監聽Bean屬性值的變化與拒絕屬性的修改
- * 監聽器類似觀察者模式觀察者角色(Observer)
- */
- public class SomeBeanPropertyListener implements PropertyChangeListener,
- VetoableChangeListener {
- public void propertyChange(PropertyChangeEvent evt) {
- //在這裏處理監聽到的事件
- System.out.println("\"" + evt.getNewValue()
- + "\" is setted to replace the old value \"" + evt.getOldValue() + "\"");
- }
- public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
- //如果設置的值爲某個特殊值(這裏爲 invalidValue ),拒絕修改
- if (evt.getNewValue().equals("invalidValue")) {
- System.out.println("\"" + evt.getNewValue()
- + "\" is try to replace the old value \"" + evt.getOldValue() + "\"");
- //拋出異常表示拒絕修改屬性
- throw new PropertyVetoException(
- "What you set \"invalidValue\" is a invalid value! operate fail!",
- evt);
- }
- }
- }
- package bean;
- import java.beans.PropertyVetoException;
- /*
- * 測試類
- */
- public class TestBean {
- public static void main(String[] args) {
- SomeBean someBean = new SomeBean();
- //添加觀察者監聽器
- someBean.addPropertyChangeListener(new SomeBeanPropertyListener());
- someBean.addVetoableChangeListener(new SomeBeanPropertyListener());
- try {
- someBean.setChangableValue("someValue");//設置
- someBean.setChangableValue("anotherValue");//修改
- someBean.setChangableValue("invalidValue");//嘗試修改成特殊值
- } catch (PropertyVetoException e) {
- System.err.println(e.getMessage());
- }
- }
- }
運行結果:
"someValue" is setted to replace the old value "null"
"anotherValue" is setted to replace the old value "someValue"
"invalidValue" is try to replace the old value "anotherValue"
What you set "invalidValue" is a invalid value! operate fail
轉載自:http://jiangzhengjun.iteye.com/blog/531649