Java对象,更改字段侦听器,设计模式

时间:2013-06-06 06:55:58

标签: java design-patterns

有一个课程:

public class MyClass {
private String field1;
private String field2;
private String field3;
// getters, setters
}

然后我们更新一些字段

MyClass myClass = new MyClass();
myClass.setField1("field1");
myClass.setField2(null);

如何知道MyClass的哪些字段被尝试更改(在上面的field1和field2示例中调用)?
什么是最好的解决方案?也许是一些设计模式?
一个选项是为此对象创建HashSet个已更改字段作为附加属性,并在每个setter中更新它,但它看起来不太好。
它是否应该像Proxy对象那样拦截所有方法调用(即setXXX())(通过Java反射?)或其他什么?

更新
似乎每个setter都应该调用一些内部方法,正如我所说的那样。我不需要通知任何其他对象有关更改。我想将所有状态存储在此对象中,以后可以访问这些更改 详细说明:如果调用方法setFieldX,则应将fieldX标记为稍后更新
附:所有字段都有不同的名称 除了反射之外的任何其他解决方案(我想通过纯setter填充对象)?

4 个答案:

答案 0 :(得分:8)

如果您想使用传统的设计模式方法实施,我建议您使用Observer Pattern

为您的班级设置字段事件的监听器

public interface FieldListener {

    public void fieldValueChanged(String fieldName, Object newValue);
}

使类实现此侦听器(Observer)

public class SampleObserver implements FieldListener {

    @Override
    public void fieldValueChanged(String fieldName, Object newValue) {
        System.out.println(fieldName + " - got set with value - " + newValue);
    }

}

在Observable类中有一个占位符(在你的情况下是MyClass),每当调用set方法时,只需触发事件。

public class MyClass {

    List<FieldListener> listeners = new ArrayList<FieldListener>(); // the placeholder for listeners

    private String field1;
    private String field2;

    /**
     * @param field1 the field1 to set
     */
    public void setField1(String field1) {
        fireEvent("field1", field1);
        this.field1 = field1;
    }
    /**
     * @param field2 the field2 to set
     */
    public void setField2(String field2) {
        fireEvent("field2", field2);
        this.field2 = field2;
    }

    public void addListener(FieldListener l) {
        if(l != null) listeners.add(l);
    }

    public void fireEvent(String fieldName, Object newValue) {
        for(FieldListener l : listeners) {
            l.fieldValueChanged(fieldName, newValue);
        }
    }

    public static void main(String [] args) {
        MyClass m = new MyClass();
        m.addListener(new SampleObserver());
        m.setField1("s");
        m.setField2("v");
    }

}

答案 1 :(得分:5)

我认为你正在搜索的是java.bean.PropertyChangeListener,它是Java中的观察者模式。

基本上,您向所有setter添加代码以调用PropertyChangeListener中的方法,以通知所有观察者该值已更改。

这是正常的Java方式。

答案 2 :(得分:2)

听起来你想要Observer / Observable模式。基本上,状态监听器向myClass对象注册(观察),以便在发生变化时接收通知。

答案 3 :(得分:2)

这很难说,因为我们不知道为什么你需要监控字段以及需要对变化做些什么。

您可以做的一件事是向对象添加侦听器(Observer模式),以便对更改感兴趣的类可以获得有关它的通知。这当然只有在您可以访问感兴趣的类并且可以相应地修改它们时才有效。

如果您无权访问任何人可以调用您的方法,您可能必须通过反思。如果您需要更好的答案,您必须提供更多详细信息。

<强>更新

由于您只想通过设置器跟踪它,因此您可以简单地放入您的设置器,无论您需要跟踪更改。一种解决方案可以是创建一个单独的类,用于存储更改。因此,每当您进行更新时,都会调用跟踪器类并告诉它您要跟踪的信息,例如旧值,新值,时间戳等等。