双向 Bean 同步

发布于 2024-12-04 13:15:08 字数 1657 浏览 1 评论 0原文

如何实现两个绑定属性之间的双向同步?实用程序类 PropertyChangeSupport 提供了一种避免无限循环的简单机制。在某些情况下,我发现它还不够。有更好的选择吗?

采用具有字符串边界属性的最简单的类:

private String myProperty;
//obviuos getter and setter omitted. (ok, setter contains propertyChangeSupport.firePropertyChange. should be obvious the same)


public void addPropertyChangeListener(PropertyChangeListener listener) {
   //delegate to propertyChangeSupport
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
   //delegate to propertyChangeSupport
}

好的。 现在,我尝试使用通知来执行此属性值之间的双向同步化,该属性值由此类的两个实例拥有。

这是(非常简单的)代码:

 public static void main(String [] args) {

    final T01 o1 = new T01();

    final T01 o2 = new T01();

    o1.addPropertyChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            o2.setMyProperty(o1.getMyProperty());
        }
    });

      o2.addPropertyChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            o1.setMyProperty(o2.getMyProperty());
        }
    });

    o1.setMyProperty("test");

}

这里没有无限循环,因为 PropertyChangeSupport当它返回到原始类时抑制通知,因为 oldValue 等于 newValue。
恕我直言,这是一个“微不足道”的实现,而更好的原则可能是“不应将事件通知给导致该事件的类”。

这种基于“等值”的实现存在的问题是:
1. 向更改的原始类引发不必要的冗余事件(然后原始类会抑制该事件)
2. 当旧值等于新值时,如果它是新值而不是“回头”值,则抑制该事件。在大多数情况下,抑制是正确的,但在某些(罕见)情况下,该事件可能是有用的。本身就是“信息丰富”的。考虑每次收到事件时都必须清除的超时。
3.它有一个“奇怪”的实现。如果你这样做:

o1.setMyProperty(null);  <br/>

你会得到无限循环和随之而来的堆栈溢出。
因为如果值等于且不为空,则事件将被抑制。但在许多情况下“null”是合法的值。

How to implement bidirectional sinchronization between two bound properties? The utility class PropertyChangeSupport provides a trivial mechanism that avoids infinite loop. In some cases I find it to be insufficient. Is there a better alternative?

Take the simplest possible class with a String bounded property:

private String myProperty;
//obviuos getter and setter omitted. (ok, setter contains propertyChangeSupport.firePropertyChange. should be obvious the same)


public void addPropertyChangeListener(PropertyChangeListener listener) {
   //delegate to propertyChangeSupport
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
   //delegate to propertyChangeSupport
}

ok.
Now I try to use notifications in order to perform bidirectional sincronization between this property value, owned by two instances of this class.

This is the (quite simple) code:

 public static void main(String [] args) {

    final T01 o1 = new T01();

    final T01 o2 = new T01();

    o1.addPropertyChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            o2.setMyProperty(o1.getMyProperty());
        }
    });

      o2.addPropertyChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            o1.setMyProperty(o2.getMyProperty());
        }
    });

    o1.setMyProperty("test");

}

Here there is no infinite loop, because the PropertyChangeSupport suppress the notification when it turns back to the originating class, because the oldValue is equal than the newValue.
IMHO this is a "trivial" implementation, while a better principle may be that "an event should NOT be notified to the class that has caused it".

The problems with this implementation based on "equal values" are:
1. raises a unnecessary, redundant event to the originating class of the change (that THEN the originating class suppresses)
2. suppresses the event when the oldvalue equals newvalue also if it is a new one and not a "turning back" one. In most cases the suppression is correct, but in some (rare) cases the event may however be useful. Be itself "informative". Think to a timeout that has to be cleared each time an event is received.
3. it has a "strange" implementation. If you do:

o1.setMyProperty(null);  <br/>

you get the infinite loop and the consequent stackoverflow.
Because the event is suppressed if the values are equals AND not null. But "null" is in many cases a legitimate value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

原来分手还会想你 2024-12-11 13:15:08

您可以尝试 jGoodies 绑定库jGoodies 绑定库 jarvana.com/jarvana/view/com/jgoodies/binding/2.0.6/binding-2.0.6-javadoc.jar!/com/jgoodies/binding/beans/PropertyConnector.html" rel="nofollow">PropertyConnector:

final T01 o1 = new T01();
final T01 o2 = new T01();
PropertyConnector.connect(o1, "myProperty", o2, "myProperty").updateProperty2();

现在 o1 的绑定属性 myProperty 将与 o2 同步,反之亦然。

You can try jGoodies Binding Library and the PropertyConnector:

final T01 o1 = new T01();
final T01 o2 = new T01();
PropertyConnector.connect(o1, "myProperty", o2, "myProperty").updateProperty2();

Now the bound property myProperty of o1 will be synchronized with o2 and vice versa.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文