【问题标题】:Design Patterns for Dynamic Inheritance动态继承的设计模式
【发布时间】:2011-04-09 04:07:38
【问题描述】:

这就是我想要做的,我不确定要寻找什么或设计它的正确方法是什么:

我正在研究应用程序的异常层次结构。作为其中的一部分,有一些异常有时是致命的,有时是可恢复的——特定实例是致命的还是可恢复的,是在运行时在异常本身中确定的。出于组织的目的,我希望能够做类似的事情(我在 python 中工作):

try:
    mightThrowAnException()
except RecoverableException:
    handleThisException()

然后我会有类似的东西:

class MyException(...):
    ...

根据构造函数中发生的情况,MyException 可以将 FatalException 或 RecoverableException 作为基类。

我知道我可以有两个单独的异常 MyFatalExceptionMyRecoverableException 然后在代码中引发一个或另一个,但是对于不同类型的错误将会有很多不同的异常,这些异常可以从代码中有多个地方,异常必须做一些事情,比如检查错误日志以确定这个实例是否应该是致命的,所以我认为将所有这些代码放入异常处理程序本身是有意义的。

有几个问题:

  1. 考虑到我想做的事情,这是一个很好的方法吗,还是有更好的设计来做这种事情?
  2. 我读过关于类工厂的文章,但我没有看到用这种方法动态更改基类的简单方法,我考虑过的其他事情是元类或覆盖 excpetion 的 __new__() 方法和我我不太确定这三种方法各自的优缺点是什么。这些是正确的方法还是我需要其他方法?

【问题讨论】:

  • 嗯。您比我更了解您的特定需求,但是对于捕获异常的代码来确定它是否是致命的不是更有意义吗?除了日志记录之外,您还如何处理致命异常?不过,一般问题仍然很有趣
  • 我怀疑我处理过的事情类似于几年前 Jesse 在 Java 项目中所描述的;它是我们应用程序的电子邮件网关。事后添加了许多错误处理和恢复。由于存在多种可能的(通常是通用的)异常类型,我们最终将它们归类为 RetryableException 和 FastFailException ,并且只会包装其中发生的任何错误,而不是声明该异常被抛出。结果没问题; Java 的检查异常让它有点复杂。

标签: python oop design-patterns exception metaprogramming


【解决方案1】:

我的建议是将异常的内容与其含义分离。同一个异常在不同的地方可以有不同的含义!

您的问题建议将异常转换为具有高级功能(例如检查日志)的“sentient”对象。但这不是例外的意图。异常应该是轻量级的数据对象,提供尽可能多的关于发生了什么的信息,但不能自行决定应该如何处理。捕获代码就是这样做的,正如我上面所说的,完全可以想象,某些异常将在某个地方以一种方式处理,而在其他地方以另一种方式处理。

【讨论】:

  • 谢谢,我想我不太确定在异常中应该处理什么样的事情。你能推荐任何读物吗?目前,我只在异常中进行错误记录。但我想要这个的原因是因为我有一些与不可靠的服务器通信的代码——这应该允许偶尔失败,但我希望异常检查我的错误日志,如果这个错误似乎发生得太频繁我需要它变得致命,因为更大的事情可能是错误的。在异常中这样做似乎是合乎逻辑的地方,你认为不是吗?
  • @Jesse,这个例外绝对不是处理这类事情的地方。应用程序应该是确定有关不可靠服务器的策略的地方。异常基本上是出现问题的消息 - 它不应包含有关做什么的说明,否则如果有已知的操作过程,则不是异常。
  • 知道了,谢谢!这让我确信我需要重构我的代码结构
【解决方案2】:

如果无法将特定异常归类为致命或可恢复,我可能只使用属性来确定异常是否致命。

class MyBaseException(Exception):
    def __init__(self, ..., fatal=True):
        self.fatal = fatal

class MyException(MyBaseException):
    ...

try:
    do_something_that_raises()
except MyBaseException, e:
    if e.fatal:
        logging.error(e)
        raise
    else:
        recover_somehow(e)

但是,异常的引发者可能不应该告诉侦听器异常是否是致命的。他们可能能够处理被视为致命的异常。异常的目的是声明出现问题,然后让潜在用户确定他们是否可以从中恢复。

【讨论】:

    猜你喜欢
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    相关资源
    最近更新 更多