我正在学习设计模式,我注意到在Observer模式的几乎所有示例实现中都有一件事是在Subject的register / unregister方法中实际上没有任何错误处理。这让我想知道如何做到这一点。
如何专门处理错误将取决于应用程序的需求,但处理这种错误的常用方法是什么?
例如,我尝试注册观察者但注册失败。该错误是否只是默默地发生,并且该特定观察者不会获得更新是可以接受的?主题是我猜的更聪明,并且可以继续通知观察者DID成功注册。
我注意到我有时很难判断一个程序中错误检查的程度是多少,并且想知道这是否是我在考虑每一个意外情况的情况之一。
答案 0 :(得分:2)
如果注册观察者失败,你肯定会引发一些错误。您的代码的客户端希望收到有关Subject中更改的通知,并且必须能够在他无法执行此操作时做出反应。但是,如果未注册一个观察者,则不应影响主体和其他观察者。事实上,您甚至可能有一个观察员观察员注册失败事件 - 元观察者; - )。
但更有趣的是,当Observer从notify
方法中抛出异常时,会发生什么?是否应该召集其他观察员?该观察员是否应该注销?谁对此错误负责?在哪里处理它?</ p>
很少有其他设计模式可以解决这个问题。您可以使用Decorator并将每个Observer包装起来,捕获从notify
抛出的异常并吞下它们(ekhem,logging)。主体甚至不会注意到,这很好。此外,其他观察员不会被打乱,因为例外被及早发现。
还要考虑将所有观察者包装成一个虚拟的观察者。然后将其装饰成前面提到的异常捕获观察者。看似相似但从一个观察者抛出的异常将阻止进一步观察者被调用。现在你甚至可以形成层次结构......
答案 1 :(得分:1)
来自观察者的通知处理程序实际上几乎不应该泄漏异常,因为通常对异常最感兴趣的唯一实体是抛出异常的观察者。异常通常意味着,“我不能做你所要求的因为X”。一个可观察的主题通常不会关心事件处理程序做任何事情,因此如果他们不这样做就不会在意。另一方面,如果异常意味着不再满足主体的类不变量,则异常可能是必要的恶意。
如果从通知处理程序抛出异常,则应该认为它非常严重(如果它是一些不应该在处理程序中捕获的圆顶愚蠢的东西,应该认真修复)。然而,在抛出异常的第一个事件处理程序之后跳过所有事件处理程序的正常Microsoft事件模式是非常糟糕的。一个更好的方法是运行所有事件处理程序,捕获发生的所有异常并将它们添加到列表中,然后最后,如果列表不为空,抛出一个EventHandlerException,其中包含所有异常列表处理事件时发生。