快速浏览一下GoF和Head First Design Patterns这本书,似乎没有提到观察者模式的无限循环检测和处理?
我认为如果是在2个类之间,我们可以更加小心无限循环问题,但是如果有5个类或12个类,并且观察者走向多个方向怎么办?在这种情况下,是否会出现无限循环并且应该在该模式中添加一些检测?
只有在以下情况下才会发生无限循环:(a) 观察者也是可观察的,(b) 他们观察到的变化可以导致自身变化,(c) 观察图是循环的,并且 (d) 存在一种最终可能发生的变化引发同类的变化。理想的解决方案是通过确保不存在这些要求之一来设计消除无限循环的风险。如果您当前的设计使所有四个都为真,请看看是否可以更改它以使其中之一为假。
Observer-Observable 的传统用途是在分层架构中 - 例如,视图控制器观察模型对象,或者事件处理程序观察 GUI 组件 - 并且这里的图不会是循环的,因此不存在无限循环的风险。
我或许应该解释一下 (d) 点,即不同类型的变化。我的意思是,如果你遇到这样的情况,比如 UserInputEvent 可以触发 ModelStateChangedEvent,而 ModelStateChangedEvent 可以触发 WidgetUpdateEvent,而 WidgetUpdateEvent 本身不能触发任何内容,那么即使观察者形成循环图,你也永远无法获得无限循环,因为事件序列中只有有限数量的阶段。实际上,事件形成了非循环图,即使观察者不这样做。但是,如果一个 ModelStateChangedEvent 可以触发另一个 ModelStateChangedEvent,那么您就有循环的风险。
如果你确实无法避免周期风险,那么你可以借鉴乔恩·波斯特尔,并使每个事件通知都带有一个整数生存时间计数器。当 Observable 广播“原始”事件(即来自观察者网络外部的事件并在其中引发一系列事件)时,它会将计数器设置为某个合适的初始 TTL 值。当 Observable 通过广播另一个事件来响应一个事件时,它将使用比触发事件小 1 的 TTL。当观察者收到 TTL 为零的通知时,它会忽略它。这可以防止无限循环,但也会阻止观察者“正确”响应某些事件,因此需要谨慎使用。我强烈建议,达到 TTL 限制的事件级联应被视为编程错误的结果,并且应以与处理 NullPointerException 或断言失败等情况相同的方式进行记录和报告。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)