我有一个接受一个对象,并做一些关于它处理的程序。 该对象可能会或可能,不是可变的。
void CommandProcessor(ICommand command) {
// do a lot of things
}
还有的是,同样的命令例如循环回在处理器的概率。 事情变得不可收拾,当这种情况发生。 我要检测这些游客返回,并防止它们被处理。 问题是我怎么能做到这一点透明,即在不干扰对象本身。
这里是我的尝试
- 新增的属性
Boolean Visited {get, set}
上ICommand
。
我不喜欢这样,因为一个模块的逻辑在其他显示出来。 该ShutdownCommand
涉及关停,不与簿记。 还有一个EatIceCreamCommand
可能总是返回False
的,希望得到更多。 一些非可变对象有一个二传手彻底的问题。
- 私下维护所有处理实例的查找表。 当一个对象来对列表中第一次检查。
我不喜欢这两种。 (1)的性能。 查找表变大。 我们需要做的线性搜索相匹配的情况。 (2)不能依靠hashcode
。 该对象可能伪造不同的哈希码不时。 (3)保持的对象列表中的防止它们被垃圾收集。
我需要一种方法来将一些看不见的标记上(的ICommand的)实例,只有我的代码可以看到。 目前我不调用的区分。 只是祈祷相同的情况下,不回来了。 没有任何人有一个更好的主意来实现这个功能..?
假设你不能只是发生在逻辑上制止这种(试图切断回路)我会去一个HashSet
,你已经看到的命令。
即使对象是违反了合同HashCode
和Equals
(我会认为是开始的一个问题),你可以创建自己IEqualityComparer<ICommand>
它使用System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode
调用Object.GetHashCode
非-virtually。 该Equals
方法也只是测试的参考身份。 所以,你的游泳池会包含不同的情况下,而无需关心命令重写是否或如何Equals
和GetHashCode
。
这只是留下垃圾堆积的问题。 假设你没有定期清洗水池的选项,你可以使用WeakReference<T>
或者非通用WeakReference
为.NET 4类),以避免物体保持。 然后你会发现所有的“死”弱引用每隔一段时间,甚至可以防止积累的。 (你比较器实际上是一个IEqualityComparer<WeakReference<T>>
在这种情况下,用于比较的身份弱引用的目标 。)
这不是特别优雅,但我认为这是在设计中固有的-你需要处理命令某处改变状态,并且不可变对象不能被定义改变状态,所以你需要的命令之外的状态。 哈希组似乎应该是一个比较合理的做法,并希望我已经说得很清楚,你如何避免这三个你提到的具体问题。
编辑:有一件事我没有考虑到的是,使用WeakReference<T>
使得它很难删除条目-当原始值是垃圾回收,你不会要能够找到它的哈希码了。 你可能只是需要创建一个新HashSet
与仍然活着的条目。 或者使用自己的LRU缓存,在注释中提到。