gpt4 book ai didi

Java - 通用 ChangeListener

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:36:44 26 4
gpt4 key购买 nike

场景:

我有一个容器对象,它包含所有继承自 MyContainedObject 类的混合对象。容器类的消费者不能直接访问包含的对象,但我有兴趣知道它们何时发生变化。

设计决策:

监听特定类类型的 ChangeEvents 的最佳方式是什么?我最初的想法是用泛型做点什么。例如,

private TreeMap<Class, ChangeListener> listeners;

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

当检测到更改时,容器类将遍历列表并仅通知为该类类型注册的监听器。

其他建议?

谢谢。

最佳答案

我假设您的 TreeMap 上的键类型是一个类,而不是 MyContainedObject。

如果您确实需要监听特定类类型的 ChangeEvents,并且您希望即使在设置监听器之后也能够将元素添加到您的集合中,这似乎很合理。您可能希望为同一类型支持多个监听器,因此您应该使用 Multimap 类(Google Collections 有一些)或使用集合(可能是 IdentityHashSet)来存储 Map 中的值。

您可能还想向 ChangeListener 添加一个类型参数,以便监听器可以获取已转换为适当类型的事件触发的对象。

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

您必须在容器内进行未经检查的强制转换才能使其正常工作,但只要您的监听器添加方法正确无误,它就应该是安全的。例如:

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;
}

一个小问题:我会避免使用“className”作为保存 Class 对象的变量的名称。类名是一个字符串,通常是 Class.getName() 等的结果。这有点烦人,但我通常看到的避免绕过“类”是保留字这一事实的约定是拼错它是“klass”或“cls”。

此外,如果您不需要在添加监听器后更新您的集合的能力,那么我会采用 akf 的建议,因为它更简单。

关于Java - 通用 ChangeListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1063956/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com