java中键值观察模式分析-PropertyChange

来源:互联网 发布:淘宝店铺首页打不开了 编辑:程序博客网 时间:2024/05/01 23:40

由于java对键值观察模式的支持比较基础,实现起来相对有些难度。目前在简单应用场景中较流行的做法是把beans实现为支持PropertyChangeSuppor(支持类)接口的对象。当客户调用beans对象的支持类接口时,通过把其委托到支持对象来实现功能。当然大部分情况下对支持接口的实现并不完全。下图为JAVA对键值观察的实现简化类图:




其中beans类是假象类,其与支持类的具体关系由实现者决定,在多数情况下一个beans对应一个支持对象即可。

从图中可知,支持类也可接受属性变化监听器代理,对应的代码如下:

public synchronizedvoid addPropertyChangeListener(String propertyName,

            PropertyChangeListener listener) {

        if ((listener != null) && (propertyName != null)) {

            List<PropertyChangeListener> listeners =

                    selectedPropertiesChangeListeners.get(propertyName);

            if (listeners == null) {

                listeners = new ArrayList<PropertyChangeListener>();

                selectedPropertiesChangeListeners.put(propertyName, listeners);

            }

            // RI compatibility

            if (listener instanceof PropertyChangeListenerProxy) {

                PropertyChangeListenerProxy proxy =

                        (PropertyChangeListenerProxy) listener;

                listeners.add(new PropertyChangeListenerProxy(

                        proxy.getPropertyName(),

                        (PropertyChangeListener) proxy.getListener()));

            } else {

                listeners.add(listener);

            }

        }

    }

public synchronizedvoid removePropertyChangeListener(String propertyName,

            PropertyChangeListener listener) {

        if ((propertyName != null) && (listener != null)) {

            List<PropertyChangeListener> listeners =

                    selectedPropertiesChangeListeners.get(propertyName);

            if (listeners != null) {

                listeners.remove(listener);

            }

        }

    }

很明显,支持对象并没有持有其代理,而是提取了其中的监听器。如客户端继承代理,会给编程带来很大的灵活性,这是一个十分重要的机制。

具体的一个实现过程如下:

1)创建beans类:

1.1)添加支持类字段;

1.2)在其中实现支持类中,对属性改变有直接作用的公有接口,并直接委托到支持对象;

1.3)实现相应的setter,在其中调用相应的firePropertyChange(propertyName,oldValue,newValue)或是firePropertyChange(PropertyChangeEvent)

2)实例化beans,并以该实例为参数实例化支持类;

3)beans对象应用到支持对象;

4)客户端实现监听器,并调用beans对象的相应接口添加或是移除监听器。



0 0