Я писал класс в javafx, где у меня было два свойства, связанных двунаправленно, и тестировал некоторые крайние случаи. Я обнаружил, что если вы измените значение одного из свойств изнутри прослушивателя аннулирования, это приведет к рассинхронизации свойств. Вот небольшой пример:
static class A {
IntegerProperty x = new SimpleIntegerProperty(this, "x", 0);
IntegerProperty y = new SimpleIntegerProperty(this, "y", 0);
A() {
x.bindBidirectional(y);
}
}
static void testA() {
A a = new A();
a.x.addListener( o -> { //InvalidationListener
if (a.x.get() < 0) a.x.set(0);
});
// after y is set to a negative value, x and y hold different values
// until either y is set to a value that's >= 0 or x is set to any value
a.y.set(-2);
System.out.println(a.x.get());
System.out.println(a.y.get());
}
Я предполагал, что при использовании двунаправленной привязки изменение одного свойства всегда приведет к обновлению другого. Кажется редким (и, возможно, неразумным), чтобы кто-то написал такой прослушиватель инвалидации, но я думаю здесь в оборонительной позиции. Если хотя бы одно из этих свойств было раскрыто, я не хочу, чтобы можно было нарушить какие-либо инварианты моего класса. Я думал, что здесь есть три возможных объяснения:
Контракт на двунаправленные привязки не заключается в том, что они всегда синхронизированы (либо они держат одинаковое значение или они помечены как недействительные), это делается по мере возможности. Таким образом, инварианты классов не должны основываться на этом факте.
Изменение значения внутри прослушивателя аннулирования нарушает предварительное условие двунаправленных привязок и должно следует избегать. В противном случае они всегда синхронизированы. Таким образом, вы можете основывать инвариант класса на этом факте, поскольку разумно потребовать, чтобы клиенты не писали такие прослушиватели недействительности.
Это ошибка, и они действительно предназначены для синхронизации, несмотря ни на что. Полагаю, если бы это было правдой, то вы могли бы легко создать бесконечный цикл уведомлений об изменениях (например, добавить прослушиватель аннулирования к y, который всегда устанавливает значение
Я писал класс в javafx, где у меня было два свойства, связанных двунаправленно, и тестировал некоторые крайние случаи. Я обнаружил, что если вы измените значение одного из свойств изнутри прослушивателя аннулирования, это приведет к рассинхронизации свойств. Вот небольшой пример: [code]static class A { IntegerProperty x = new SimpleIntegerProperty(this, "x", 0); IntegerProperty y = new SimpleIntegerProperty(this, "y", 0); A() { x.bindBidirectional(y); } }
static void testA() { A a = new A(); a.x.addListener( o -> { //InvalidationListener if (a.x.get() < 0) a.x.set(0); }); // after y is set to a negative value, x and y hold different values // until either y is set to a value that's >= 0 or x is set to any value a.y.set(-2); System.out.println(a.x.get()); System.out.println(a.y.get()); } [/code] Выход: [code]0 -2 [/code] Я предполагал, что при использовании двунаправленной привязки изменение одного свойства всегда приведет к обновлению другого. Кажется редким (и, возможно, неразумным), чтобы кто-то написал такой прослушиватель инвалидации, но я думаю здесь в оборонительной позиции. Если хотя бы одно из этих свойств было раскрыто, я не хочу, чтобы можно было нарушить какие-либо инварианты моего класса. Я думал, что здесь есть три возможных объяснения: [list] [*]Контракт на двунаправленные привязки не заключается в том, что они всегда синхронизированы (либо они держат одинаковое значение или они помечены как недействительные), это делается по мере возможности. Таким образом, инварианты классов не должны основываться на этом факте.
[*]Изменение значения внутри прослушивателя аннулирования нарушает предварительное условие двунаправленных привязок и должно следует избегать. В противном случае они всегда синхронизированы. Таким образом, вы можете основывать инвариант класса на этом факте, поскольку разумно потребовать, чтобы клиенты не писали такие прослушиватели недействительности.
[*] Это ошибка, и они действительно предназначены для синхронизации, несмотря ни на что. Полагаю, если бы это было правдой, то вы могли бы легко создать бесконечный цикл уведомлений об изменениях (например, добавить прослушиватель аннулирования к y, который всегда устанавливает значение