двунаправленная синхронизация bean-компонентов - PullRequest
3 голосов
/ 12 сентября 2011

Как реализовать двунаправленную синхронизацию между двумя связанными свойствами?Служебный класс PropertyChangeSupport предоставляет тривиальный механизм, позволяющий избежать бесконечного цикла.В некоторых случаях я считаю, что этого недостаточно.Есть ли лучшая альтернатива?

Возьмем простейший из возможных классов с ограниченным свойством String:

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.Теперь я пытаюсь использовать уведомления, чтобы выполнить двунаправленную синхронизацию между значением этого свойства, принадлежащего двум экземплярам этого класса.

Это (довольно простой) код:

 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/>

вы получаете бесконечный цикл и последующий стекопоток.Потому что событие подавляется, если значения равны И не ноль.Но «ноль» во многих случаях является законной ценностью.

1 Ответ

1 голос
/ 13 сентября 2011

Вы можете попробовать jGoodies Binding Library и PropertyConnector :

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

Теперь связанное свойство myProperty из o1 будет синхронизировано с o2 и наоборот.

...