【问题标题】:How to detect modifications in an object?如何检测对象的修改?
【发布时间】:2016-10-26 22:34:23
【问题描述】:

假设我有一个项目集合,例如 List<Item>,我需要检查是否有任何项目是从包装类修改的,例如,任何项目属性的值通过二传手:

List<Item> items = itemsWrapper.getItems(); // itemsWrapper contains a list of items
Item anItem = items.get(index);
item.setProperty(property);
itemsWrapper.hasChanged(); // ??????

我正在尝试找出实现最后一条语句的方法,或类似的方法。

我可以看到有类似的问题,例如 this one 建议使用 Hibernate 但答案非常模糊,而且我的问题与数据库无关。它还提到了建立一个听众名单,但我不确定他怎么做。

this other question,其中选择的答案建议使用dirty 标志,每次修改属性时都需要升起该标志。然而,自相矛盾的是,我的类实际上会变得dirtier,而且我需要修改许多修改项目属性的方法。

是否有其他方法,最好是透明的?

【问题讨论】:

  • “观察者”模式:itemsWrapper 观察项目的变化。
  • 你能给我们更多的背景信息吗?我怀疑您可能希望监视其他地方的更改,而不是集合本身。
  • @Fildor 我还检查了观察者模式方法,但我看不出它与 dirty 标志方法在实际“使我的代码更脏”方面有何不同,因为我仍然会有更新我所有的设置器(和对象修改方法)。
  • @TimBiegeleisen 真的没什么。实际情况实际上不是List&lt;Item&gt;,而是对我的项目更具体的东西,但我追求的想法是一样的。我需要知道集合中的任何项目是否更改(不是添加、删除或替换它们,而是实际对象是否更改)。
  • 是的,您必须更改您的代码。几乎没有办法绕过它。否则,您必须将所有项目的某个状态与实际状态进行比较。当然,这本身就是大量更改的代码...

标签: java


【解决方案1】:

最好的方法是使用java.util.Observable 类,它具有boolean hasChanged() 的功能,如您的用例所述。 这是参考答案: When should we use Observer and Observable

只是一个例子:

<code>import java.util.Observable;
import java.util.Observer;
// First observer 
class FirstNewsReader implements Observer {
    public void update(Observable obj, Object arg) {
        System.out.println("FirstNewsReader got The news:"+(String)arg);
    }
}
//Second Observer
class SecondNewsReader implements Observer {
    public void update(Observable obj, Object arg) {
        System.out.println("SecondNewsReader got The news:"+(String)arg);
    }
}
// This is the class being observed.
class News extends Observable {
    void news() {
        String[] news = {"News 1", "News 2", "News 3"};
        for(String s: news){
            //set change
            setChanged();
            //notify observers for change
            notifyObservers(s);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("Error Occurred.");
            }
        }
    }
}
//Run Observer and Observable
class ObserverObservableDemo {
    public static void main(String args[]) {
        News observedNews = new News();
        FirstNewsReader reader1 = new FirstNewsReader();
        SecondNewsReader reader2 = new SecondNewsReader();
        observedNews.addObserver(reader1);
        observedNews.addObserver(reader2);
        observedNews.news();        
    }
}</code>

【讨论】:

  • 您能否简要介绍一下由此产生的类布局?我不知道我应该如何设置它。
【解决方案2】:

最透明的方式是使用 Spring AOP AspectJ。创建您的 Aspect 类并为您的 item.setProperty() 方法使用 @Before 或 @after 注释。

【讨论】:

【解决方案3】:

为您的Item/wrapper 类使用观察者模式。 JavaFX(自 java 7.something 起包含)属性已经支持提供对此类功能的支持。

例子:

class Item {

    private final ObjectProperty<Object> property = new SimpleObjectProperty<Object>();

    public final Object getProperty() {
        return this.property.get();
    }

    public final void setProperty(Object value) {
        this.property.set(value);
    }

    public final ObjectProperty<Object> propertyProperty() {
        return this.property;
    }
}
class Listener implements InvalidationListener {

    private boolean changed = false;

    @Override
    public void invalidated(Observable observable) {
        changed = true;
    }

    public boolean isChanged() {
        return changed;
    }

    public void resetChanged() {
        this.changed = false;
    }

}
// trigger update changes when the property changes
ObservableList<Item> list = FXCollections.observableArrayList(e -> new Observable[]{e.propertyProperty()});

list.addAll(new Item(), new Item());

Listener listener = new Listener();
list.addListener(listener);
System.out.println(listener.isChanged());

list.get(0).setProperty("");
System.out.println(listener.isChanged());
listener.resetChanged();

list.get(1).setProperty(1);
System.out.println(listener.isChanged());

listener.resetChanged();

list.add(new Item());
System.out.println(listener.isChanged());

【讨论】:

    【解决方案4】:

    简单地说,让对象私有广告为其创建 getter 和 setter。这样您就可以在包装器更改列表中的任何内容时获得。

    如果你想检测,当一个新元素被放入列表时,你可以创建第三个 adder 方法来将元素添加到数组中。

    【讨论】:

    • @TimBiegeleisen 已更正
    猜你喜欢
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 2016-11-05
    • 2011-11-15
    • 1970-01-01
    • 2019-09-21
    相关资源
    最近更新 更多