I respect your point of view. Thank you for a thorough response.


On 22 Jan 2014, at 12:18, Martin Sladecek <martin.slade...@oracle.com> wrote:

> On 01/22/2014 11:38 AM, Randahl Fink Isaksen wrote:
>> Hi Martin
>> Then I respectfully disagree with this design decision. In my point of view, 
>> choosing performance over ease of use is rarely a good idea. Here, the 
>> performance choice has put us in a situation where no one knows how many 
>> JavaFX apps have duplicate listener bugs, and such bugs can be very hard to 
>> debug.
>> Have anyone done any tests that prove that avoiding listener duplicates 
>> would lead to a severe performance impact?
> I'm not the original author of the Observable API, but I remember there were 
> many performance tests back at the days before 2.0 release, esp. when such 
> API decision was made. So likely, the tests were done, but the results were 
> not archived or anything.
>> I understand, that if all observables had thousands of listeners and we 
>> searched for a possible duplicate using an inefficient linear search, we 
>> would have a problem. But if reality is that very few observables have more 
>> than 20 listeners and these could be stored in a map for efficient duplicate 
>> checking, then what is the problem?
> Well it's always a balance between performance, dynamic footprint (a set/map 
> for duplicates) and API. Having an API that extensively checks for all the 
> mistakes a developer can do is an extreme case in the same manner as an API 
> that does not check input at all. If a cleanup of some listeners is missing, 
> it's a developer's bug (memory leak) no matter if there a duplicate listener 
> check or not on the subsequent addListener call when the object becomes 
> "valid" again (or whatnot).
> I understand your position, there are APIs I would also like to behave 
> differently, but the decision was already made, it's too late for the 
> discussion. There might be 3rd implementations that use a list a don't 
> guarantee a duplicate check, we don't want to make them suddenly "broken".
> I also disagree that such bugs are hard to debug, a simple printout should do.
> In many cases it would likely just make a computations run more times than 
> necessary. I can imagine doing a duplicate check on something like 
> -Djavafx.debug=true.
> Regards,
> -Martin
>> Yours
>> Randahl
>>  On 22 Jan 2014, at 11:26, Martin Sladecek <martin.slade...@oracle.com> 
>> wrote:
>>> The reason why this was decided this way is simple : performance. You 
>>> usually don't (try to) add a listener twice, so in most cases it doesn't 
>>> make sense to check for duplicates every time a listener is added. So we 
>>> currently leave the burden of avoiding duplicates on the developer.
>>> -Martin
>>> On 01/22/2014 11:23 AM, Randahl Fink Isaksen wrote:
>>>> Hi Martin
>>>> While I agree your proposed solution would work, I still don’t understand 
>>>> why JavaFX should keep on supporting duplicates in listener collections. 
>>>> Can anyone come up with just 1 example of an application that might be 
>>>> depending on having two listeners on the same Observable? E.g. this kind 
>>>> of code:
>>>> myObservable.addListener(myChangeListener); //add it
>>>> myObservable.addListener(myChangeListener); //add it again
>>>> In what kind of situation would this sort of code make any sense?
>>>> If we all feel confident that the presence of duplicates listeners is 
>>>> always an error, I warmly recommend changing the API to be duplicate free.
>>>> Yours
>>>> Randahl
>>>> On 22 Jan 2014, at 11:07, Martin Sladecek <martin.slade...@oracle.com> 
>>>> wrote:
>>>>> Hi all,
>>>>> I would like to start discussion about an addition to API in Observable, 
>>>>> ObservableValue and all Observable collections.
>>>>> There were multiple requests for a way how to avoid duplicates in 
>>>>> listeners lists. The way RT-25613 solves this is that it introduces 
>>>>> public boolean hasListener(ListenerType listener) which would return true 
>>>>> if the provided listener is already registered.
>>>>> This has one significant drawback that all of Observable* are actually 
>>>>> interfaces. Means we can only add hasListener as a defender method. The 
>>>>> problem is with the default implementation. We cannot return anything 
>>>>> meaningful, so we have to throw an UnsupportedOperationException. The 
>>>>> problem is that this might blow up unexpectedly when some "older" 
>>>>> Observable implementation is used. Also, it might be easy to miss when 
>>>>> implementing the interface, since the IDE might not force you to 
>>>>> implement it.
>>>>> So as an alternative solution, I propose adding something like:
>>>>> ensureListener(ListenerType listener)
>>>>> which would make sure the listener is on the list and if a listener is 
>>>>> already present, the number of times listener is registered on the 
>>>>> Observable will NOT grow after this call.
>>>>> The default implementation (for Observable) would look like this:
>>>>> public default void ensureListener(InvalidationListener listener) {
>>>>>    removeListener(listener);
>>>>>    addListener(listener);
>>>>> }
>>>>> subclasses might do something more effective. The same would apply to 
>>>>> ObservableValue and ChangeListener and Observable[List|Set|Map] and 
>>>>> [List|Set|Map]ChangeListener.
>>>>> What do you think?
>>>>> JIRA link: https://javafx-jira.kenai.com/browse/RT-25613
>>>>> -Martin

Reply via email to