冲压/标记/品牌对象实例(Stamping / Tagging / Branding Object

2019-10-18 06:13发布

我有一个接受一个对象,并做一些关于它处理的程序。 该对象可能会或可能,不是可变的。

void CommandProcessor(ICommand command) {
    // do a lot of things
}

还有的是,同样的命令例如循环回在处理器的概率。 事情变得不可收拾,当这种情况发生。 我要检测这些游客返回,并防止它们被处理。 问题是我怎么能做到这一点透明,即在不干扰对象本身。

这里是我的尝试

  • 新增的属性Boolean Visited {get, set}ICommand

我不喜欢这样,因为一个模块的逻辑在其他显示出来。 该ShutdownCommand涉及关停,不与簿记。 还有一个EatIceCreamCommand可能总是返回False的,希望得到更多。 一些非可变对象有一个二传手彻底的问题。

  • 私下维护所有处理实例的查找表。 当一个对象来对列表中第一次检查。

我不喜欢这两种。 (1)的性能。 查找表变大。 我们需要做的线性搜索相匹配的情况。 (2)不能依靠hashcode 。 该对象可能伪造不同的哈希码不时。 (3)保持的对象列表中的防止它们被垃圾收集。

我需要一种方法来将一些看不见的标记上(的ICommand的)实例,只有我的代码可以看到。 目前我不调用的区分。 只是祈祷相同的情况下,不回来了。 没有任何人有一个更好的主意来实现这个功能..?

Answer 1:

假设你不能只是发生在逻辑上制止这种(试图切断回路)我会去一个HashSet ,你已经看到的命令。

即使对象是违反了合同HashCodeEquals (我会认为是开始的一个问题),你可以创建自己IEqualityComparer<ICommand>它使用System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode调用Object.GetHashCode非-virtually。 该Equals方法也只是测试的参考身份。 所以,你的游泳池会包含不同的情况下,而无需关心命令重写是否或如何EqualsGetHashCode

这只是留下垃圾堆积的问题。 假设你没有定期清洗水池的选项,你可以使用WeakReference<T>或者非通用WeakReference为.NET 4类),以避免物体保持。 然后你会发现所有的“死”弱引用每隔一段时间,甚至可以防止积累的。 (你比较器实际上是一个IEqualityComparer<WeakReference<T>>在这种情况下,用于比较的身份弱引用的目标 。)

这不是特别优雅,但我认为这是在设计中固有的-你需要处理命令某处改变状态,并且不可变对象不能被定义改变状态,所以你需要的命令之外的状态。 哈希组似乎应该是一个比较合理的做法,并希望我已经说得很清楚,你如何避免这三个你提到的具体问题。

编辑:有一件事我没有考虑到的是,使用WeakReference<T>使得它很难删除条目-当原始值是垃圾回收,你不会要能够找到它的哈希码了。 你可能只是需要创建一个新HashSet与仍然活着的条目。 或者使用自己的LRU缓存,在注释中提到。



文章来源: Stamping / Tagging / Branding Object Instances