我有一个用例,我想将多个ObservableValue
绑定到一个Observable
上,因为我实际上并不感兴趣,值的变化是什么,我只需要一种方法来获得通知当它改变时。
这是Observable绑定,我上来了:
BooleanBinding() {
{
super.bind(proxy.activeShipProperty());
INavigableVessel activeShip = proxy.getActiveShip();
super.bind(activeShip.getLoadBinding());
if (activeShip instanceof IShip) {
super.bind(((IShip) activeShip).travelState());
} else {
super.bind(((IConvoy) activeShip).getOrlegShip().travelState());
}
super.bind(date.dayDateBinding());
}
private boolean value = true;
@Override
protected boolean computeValue() {
value = !value;
return value;
}
};
然后是此测试代码,以验证其是否按预期工作:
Observable observable = contentProvider.createObservable(ENoticeBoardType.SHIP_WARE_INFO, proxy);
IntegerProperty invalidationCounter = new SimpleIntegerProperty(0);
InvalidationListener listener = observable1 -> invalidationCounter.setValue(invalidationCounter.get() + 1);
observable.addListener(listener);
// When
dayBinding.invalidate();
loadBinding.invalidate();
travelState.set(EShipTravelState.ANCHOR);
activeVessel.set(mock(IShip.class));
// Then
assertEquals(4, invalidationCounter.get());
事实并非如此。在第一个无效调用中,invalidationCounter仅增加一次。
不过,当我从上方以ObservableValue
处理BooleanBinding时,可以添加一个ChangeListener:
ChangeListener listener = (obs, oldValue, newValue) -> invalidationCounter.setValue(invalidationCounter.get() + 1);
observable.addListener(listener);
// When
dayBinding.invalidate();
loadBinding.invalidate();
travelState.set(EShipTravelState.ANCHOR);
activeVessel.set(mock(IShip.class));
// Then
assertEquals(4, invalidationCounter.get());
这按预期工作。
我想知道/已经确认的内容:InvalidationListener仅被调用一次,当Observable
变为无效时,它便不会变回有效,因此它可以再次变为有效。但是,对于ChangeListener
,则必须计算新值,因此ObservableValue
再次有效。
基于这种观察,我实际上可以使用Observable
的任何用例吗?
答案 0 :(得分:4)
std::less
只是一个接口,由实现确定是否调用Observable
会以某种状态触发侦听器。您在此处观察到的行为是invalidate
仅触发一次BooleanBinding
更新,直到使用invalidation
方法检索到值为止。
希望观察者知道一旦通知了听者,该值可能会发生变化。
这是为了避免不必要的计算而进行的优化。例如。请考虑以下情形:有三个get()
,BooleanProperty
,b1
和b2
,而您对b3
感兴趣。在这种情况下,如果b1 && (b2 || b3)
为(b2 || b3)
,则可以应用不需要评估b1
的短路评估,而评估false
不需要评估{{1 }},如果(b2 || b3)
是b3
。如果b2
和/或true
的计算成本很高,则可以避免不评估它们,从而使代码的性能更高,例如可以避免。使用以下实现
b2
与b3
相比, BooleanBinding binding = new BooleanBinding() {
{
bind(b1, b2, b3);
}
@Override
protected boolean computeValue() {
if (!b1.get()) {
return false;
}
if (b2.get()) {
return true;
} else {
return b3.get();
}
// the above is basically a longer version of
// return b1.get() && (b2.get() || b3.get());
// to highlight the short circuiting behaviour
}
};
要求将新值传递给他们,因此添加任何ChangeListener
会导致调用InvalidationListener
并导致每个{{1} }通话会触发ChangeListener
的通话。