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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16955588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 00:31:16  来源:igfitidea点击:

Java object, changed fields listener, design-pattern

javadesign-patterns

提问by Alex

There is a class:

有一个类:

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

Then we update some fields

然后我们更新一些字段

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

How can I know which fields of MyClass were tried to be changed (invoked, in the example above field1 and field2)?
What is the best solution for that? Maybe some design-pattern?
One option is to create HashSetof changed fields for this object as an additional property and update it inside each setter but it does not seem nice.
Should it be something like Proxy object which will be intercept all method calls (i.e. setXXX()) (through Java reflection?) or anything else?

我如何知道尝试更改 MyClass 的哪些字段(在上面的 field1 和 field2 示例中被调用)?
什么是最好的解决方案?也许一些设计模式?
一种选择是HashSet为此对象创建已更改的字段作为附加属性并在每个 setter 中更新它,但这似乎不太好。
它应该是类似于 Proxy 对象的东西,它将拦截所有方法调用(即 setXXX())(通过 Java 反射?)还是其他任何东西?

UPDATE
It seems that each setter should invoke some inner method what does not seem nice as I said. And I don't need to notify any other objects about changes. I would like to store all states in this object and have access to these changes later.
In details: if method setFieldX invoked then fieldX should be marked to be updated later
P.S. All fields have different names.
Any other solutions except reflection (I want to populate object via pure setter)?

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

回答by sanbhat

If you want to implement using conventional design-pattern approach, I would recommend using Observer Pattern

如果你想使用传统的设计模式方法来实现,我会推荐使用观察者模式

Have a Listener for set field event of your class

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

public interface FieldListener {

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

Make a class implement this listener (Observer)

让一个类实现这个监听器(观察者)

public class SampleObserver implements FieldListener {

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

}

have a place-holder for your listeners in the Observable class (in your case MyClass) and whenever the set method gets called, just fire the event.

在 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");
    }

}

回答by Uwe Plonus

I think what you are searching the a java.bean.PropertyChangeListenerwhich is the Observer-Pattern in Java.

我认为您正在搜索的 ajava.bean.PropertyChangeListener是 Java 中的观察者模式。

Basically you add code to all setters to call the method in the PropertyChangeListenerto inform all observers that the value is changed.

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

This is the normal Java way.

这是正常的Java方式。

回答by Tim Bender

Sounds like you want the Observer/Observablepattern. Basically a state listener registers (observes) with the myClassobject to receive a notification when something changes.

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

回答by Devolus

That's hard to say, because we don't know why you need to monitor the fields and what neds to be done with the changes.

这很难说,因为我们不知道您为什么需要监视字段以及需要对更改执行哪些操作。

One thing you could do is to add listeners to your object (Observer pattern), so that classes, interested in the changes, can get notified about it. This of course works only if you have access to the interested classes and can modify them accordingly.

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

If you have no access and anybody can call your methods, you might have to go via reflection. If you need a better answer, you must give more details.

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

Update

更新

Since you only want to keep track of it internaly via setters, then you can simply put in your setter, whatever you need to keep track of the changes. One solution could be to create a separate class, which stores the changes. So whenever you do some update, you call the tracker class and tell it the information you want to keep track of, like old value, new value, timestamp, whatever.

由于您只想通过设置器在内部跟踪它,因此您可以简单地放入您的设置器,无论您需要什么来跟踪更改。一种解决方案可能是创建一个单独的类来存储更改。所以每当你做一些更新时,你调用跟踪器类并告诉它你想要跟踪的信息,比如旧值、新值、时间戳等等。