The suspicious thing about your solution is that your smart
implementation of equals() is not symmetric.

In case the observable value is visible only within your project, you
could do this:

    interface Subscription {
        void unsubscribe();
    }

    class MyObservableValue<T> implements ObservableValue<T> {
        public Subscription subscribe(ChangeListener<? extends T> listener) {
            ChangeListener<T> decorated = decorate(listener);
           addListener(decorated);
           return () -> removeListener(decorated);
        }
    }

and use subscribe()/unsubscribe() instead of addListener()/removeListener():

    Subscription sub = observableValue.subscribe(listener);
    // ...
    sub.unsubscribe();

Of course this is not possible if you need to pass the observable
value to the outside world as ObservableValue.

Regards,
Tomas

On Sat, Mar 22, 2014 at 6:57 AM, Mario Ivankovits <ma...@datenwort.at> wrote:
> Hi!
>
> In one of my ObservableValue implementations I do have the need to decorate 
> ChangeListener added to it.
> Today this is somewhat complicated to implement, as I have to keep a map of 
> the original listener to the decorated one to being able to handle the 
> removal process of a listener. Because the outside World did not know that I 
> decorated the listener and the instance passed in to removeListener ist the 
> undecorated one.
>
> We can make things easier with a small change in 
> ExpressionHelper.removeListener. When iterating through the listener list, 
> the listener passed in as argument to removeListener is asked if it is equal 
> to the one stored
>
>                     if (listener.equals(changeListeners[index])) {
>
> If we flip this to
>
>                 if (changeListeners[index].equals(listener)) {
>
> a listener decoration can be smart enough to not only check against itself, 
> but also against its delegate.
>
> What do you think?
>
> I could prepare a patch for the *ExpressionHelper classes.
>
>
> Best regards,
> Mario
>
>

Reply via email to