Java – Generic ChangeListener

Scenario:

I have a container object that contains a mixed object package. All objects inherit from the mycontainerdobject class Consumers of container classes cannot directly access the contained objects, but I'm interested in knowing when they change

Design decisions:

What is the best way to listen for changeevents on a particular class type? My initial idea was to do something with generics For example,

private TreeMap<Class,changelistener> listeners;

public <T extends MyContainedObject> addchangelistenerForObjectsOfType(Class<T> className,changelistener listener)
{
   listeners.put(className,listener);
}

When a change is detected, the container class traverses the list and notifies only the listeners registered for that class type

Other suggestions?

thank you.

Solution

I assume that the key type on your treemap is a class, not mycontainedobject

If you really need to listen to changeevents on a specific class type, and you want to be able to add elements to your collection even after setting the listener, it seems reasonable You may want to support multiple listeners of the same type, so you should use the Multimap class (some of Google collections) or the collection (possibly identityhashset) as the value in the map

You may also want to add a type parameter to changelistener so that the listener can get that the triggered event has been converted to an object of the appropriate type

interface changelistener<T> {
    void changed(T obj,/* whatever */);
}

You must make an unchecked cast inside the container to make it work, but as long as your listener addition method does the right thing, it should be safe For example:

public <T extends MyContainedObject> addchangelistener(Class<T> klass,changelistener<? super T> listener) {
    ...
}    

private <T extends MyContainedObject> Set<changelistener<? super T>> getchangelisteners(T obj) {
    Set<changelistener<? super T>> result = new IdentityHashSet<changelistener<? super T>>();
    for (Map.Entry<Class<? extends MyContainedObject>,Set<changelistener<?>>> entry : listeners.entrySet()) {
        if (entry.getKey().isinstance(obj)) {
            // safe because signature of addchangelistener guarantees type match
            @SuppressWarnings("unchecked")
            Set<changelistener<? super T>> listeners =
                (Set<changelistener<? super T>>) entry.getValue();
            result.addAll(listeners);
        }
    }
    return result;
}

A small problem: I avoid using "classname" as the name of variables containing class objects The class name is a string, usually class Getname(), etc This is a bit annoying, but the usual practice I see is to avoid misspelling around the fact that "class" is a reserved word. It can be "Klass" or "CLS"

In addition, if you don't need the ability to update the collection after adding listeners, I'll choose the content suggested by AKF because it's simpler

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>