场景:
我有一个容器对象,它包含一个混合的对象包,所有对象都继承自MyContainedObject类.容器类的使用者无法直接访问包含的对象,但我有兴趣知道它们何时发生更改.
设计决策:
在特定类类型上侦听ChangeEvents的最佳方法是什么?我最初的想法是用泛型做点什么.例如,
private TreeMap<Class, ChangeListener> listeners;
public <T extends MyContainedObject> addChangeListenerForObjectsOfType(Class<T> className, ChangeListener listener)
{
listeners.put(className, listener);
}
Run Code Online (Sandbox Code Playgroud)
当检测到更改时,容器类将遍历列表并仅通知为该类类型注册的侦听器.
其他建议?
谢谢.
我假设你的TreeMap上的键类型是一个类,而不是MyContainedObject.
如果你真的需要在特定的类类型上监听ChangeEvents,并且你希望即使在设置了监听器之后也能够向你的集合中添加元素,这看起来很合理.您可能希望支持相同类型的多个侦听器,因此您应该使用Multimap类(Google Collections有一些)或使用集合(可能是IdentityHashSet)作为Map中的值.
您可能还希望向ChangeListener添加一个类型参数,以便侦听器可以获取已触发的事件已经转换为适当类型的对象.
interface ChangeListener<T> {
void changed(T obj, /* whatever */);
}
Run Code Online (Sandbox Code Playgroud)
您必须在容器内部进行未经检查的强制转换才能使其正常工作,但只要您的侦听器添加方法做正确的事情,它就应该是安全的.例如:
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;
}
Run Code Online (Sandbox Code Playgroud)
一个小问题:我避免使用"className"作为包含Class对象的变量的名称.类名是String,通常是Class.getName()等的结果.它有点烦人,但我通常看到的惯例是避免绕过"class"是保留字的事实拼错它可以是"klass"或"cls".
此外,如果您在添加听众后不需要更新集合的能力,那么我会选择akf建议的内容,因为它更简单.
| 归档时间: |
|
| 查看次数: |
5286 次 |
| 最近记录: |