【问题标题】:What are the common error handling mechanisms for the Observer pattern?观察者模式常见的错误处理机制是什么?
【发布时间】:2011-07-16 00:46:11
【问题描述】:
我正在学习设计模式,在观察者模式的几乎所有示例实现中我注意到的一件事是,在 Subject 的注册/注销方法中实际上没有任何错误处理。这让我想知道如何/如果这样做。
具体如何处理错误取决于应用程序的需求,但处理此类错误的常用方法是什么?
例如,我尝试注册一个观察者,但注册失败。该错误是否只是默默地发生并且该特定观察者不会获得更新是可以接受的?我猜 Subject 并没有更聪明,可以继续通知 DID 成功注册的观察者。
我注意到我有时很难判断程序中多少错误检查就足够了,我想知道这是否是我过度考虑每种意外情况的情况之一。
【问题讨论】:
标签:
design-patterns
error-handling
observer-pattern
【解决方案1】:
如果注册观察者失败,你肯定应该提出一些错误。您的代码的客户端希望收到有关主题更改的通知,并且当他无法执行此操作时,它必须能够做出反应。但是没有注册一个观察者根本不应该影响主题和其他观察者。事实上,您甚至可能有一个观察者观察者注册失败事件 - 元观察者;-)。
但是更有趣的方面恕我直言,当观察者从其notify 方法中抛出异常时应该发生什么?是否应该调用其余的观察者?这个观察者应该被注销吗?谁对这个错误负责?以及在哪里处理?
很少有其他设计模式可以解决这个问题。您可以使用装饰器并包装每个观察者捕获从notify 抛出的异常并吞下它们(ekhem,日志记录)。对象甚至不会注意到,这很好。此外,其他 Observers 不会被中断,因为异常被足够早地捕获。
还可以考虑使用 Composite 将所有观察者包装成一个虚拟。然后将其装饰为上述异常捕获观察者。看起来很相似,但是从一个观察者抛出的异常会阻止进一步的观察者被调用。现在你甚至可以形成层次结构......
【解决方案2】:
来自观察者的通知处理程序实际上几乎不应该泄漏异常,因为通常对异常最感兴趣的唯一实体是抛出它的观察者。一个例外通常意味着,本质上,“我不能做你要求的事情,因为 X”。一个可观察的主题通常不会关心事件处理程序做任何事情,因此不会关心他们是否没有做到这一点。另一方面,如果异常意味着不再满足主体的类不变量,那么异常可能是必要的恶。
如果从通知处理程序抛出异常,则应该非常认真地对待它(如果它是一些不应该在处理程序中捕获的愚蠢的事情,那么应该认真修复)。然而,在第一个引发异常的事件处理程序之后跳过所有事件处理程序的正常 Microsoft 事件模式是一个非常糟糕的事件模式。更好的方法是运行所有事件处理程序,捕获所有发生的异常并将它们添加到列表中,然后在最后,如果列表不为空,则抛出 EventHandlerException,其中包含所有异常的列表在处理事件时发生。