快速浏览GoF和Head First Design Patterns一书,似乎没有提到Observer模式的无限循环检测和处理?
我认为如果它在两个类之间,我们可以更加小心无限循环问题,但如果有5个类或12个类,并且观察者进行多方向怎么办?在这种情况下,是否可以进行无限循环,并且应该在此模式中添加一些检测?
Tom*_*son 10
无限循环只有在以下情况下才会发生:(a)观察者也是可观察的,(b)他们观察到的变化本身会导致变化,(c)观察图是循环的,(d)有一种变化可能最终触发相同类型的更改.理想的解决方案是通过确保缺少其中一个要求来设计无限循环的风险.如果您当前的设计使所有四个都成立,请查看您是否可以更改它以使其中一个为假.
Observer-Observable的传统用法是在分层体系结构中 - 例如,视图控制器观察模型对象,或者事件处理程序观察GUI组件 - 这里,图形不是循环的,因此不存在无限循环的风险.
关于不同类型的变化,我应该解释一下(d)点.我的意思是,如果你有一种情况,例如,UserInputEvent可以触发ModelStateChangedEvent,而ModelStateChangedEvent可以触发WidgetUpdateEvent,它本身不能触发任何东西,那么即使观察者形成一个循环图,你也永远不会获得无限循环,因为事件序列中只有有限数量的阶段.实际上,即使观察者没有,事件也会形成一个非循环图.但是,如果ModelStateChangedEvent可以触发另一个ModelStateChangedEvent,那么您将面临循环风险.
如果你真的无法避免周期风险,那么你可以从Jon Postel那里窃取一个想法,并使每个事件通知带有一个整数生存时间计数器.当一个Observable广播一个'原始'事件,意味着从观察者网络外部传来的东西并开始其中的一连串事件时,它将计数器设置为一些合适的初始TTL值.当Observable通过广播另一个事件来响应事件时,它将使用比触发事件小TTL的TTL.当Observer收到TTL为零的通知时,它会忽略它.这样可以防止无限循环,但也会阻止Observer"正确"响应某些事件,所以谨慎使用它是一个想法.我强烈建议事件级联达到TTL限制应该被认为是编程错误的结果,并且应该以与处理NullPointerException或断言失败相同的方式记录和报告.