JavaBean 中的属性
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!