2011-04-09 60 views
2

这里就是我想要做的,我不知道要寻找什么,或者什么设计正确的方法是:设计模式为动态继承

我正在一个异常层次结构的应用。作为其中的一部分,有一些例外有时会致命,其他时间是可以恢复的 - 无论是特定的实例是致命的还是可恢复的,都是在异常本身的运行时确定的。对于组织的目的,我希望能够像做(我在python工作):

try: 
    mightThrowAnException() 
except RecoverableException: 
    handleThisException() 

然后我会碰到这样的:

class MyException(...): 
    ... 

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

我知道我可以有两个单独的异常MyFatalExceptionMyRecoverableException再提高一个或有其他的代码,但有将是一个很大的不同异常的不同类型的错误,它可以从多个地方被上调代码和异常必须做一些事情,比如检查错误日志以确定这个实例是否应该是致命的,所以我认为将所有这些代码放入异常处理程序本身是有意义的。

那么几个问题:

  1. 鉴于我想要做什么,这是一个很好的方式去了解它,或者是有这样的事情更好的设计?
  2. 我读过关于类工厂,但我没有看到用这种方法动态更改基类的简单方法,我考虑的其他事情是元类或重写删除方法__new__(),我不是真的确定这三种方法各有利弊。这些都是正确的方法还是我需要别的东西?
+0

嗯。您比我更了解您的特定需求,但是对于捕获异常以确定其是否致命的代码,在逐案的基础上进行更合理吗?除了日志以外,你甚至可以处理一个致命的异常?虽然 – Cameron 2011-04-09 04:14:16

+0

我怀疑我已经处理了几年前Jesse在Java项目中描述的类似问题,但总的问题仍然很有趣,它是我们应用程序的电子邮件网关。事实之后添加了很多错误处理和恢复。由于存在各种可能的(通常是泛型的)异常类型,我们最终将它们归类为RetryableException和FastFailException,并且只是将发生的任何错误都包装进去,而不是将该异常声明为抛出异常。它成功了, Java的检查异常使它有点复杂。 – 2011-04-09 04:49:56

回答

6

我的建议是将例外的内容与其含义分离。同样的例外可以在不同的地方有不同的含义!

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

+0

谢谢,我想我不确定在异常情况下应该处理什么样的事情。你能推荐任何阅读吗?目前,我只在异常中进行错误日志记录。但我想要这样做的原因是因为我有一些代码与不可靠的服务器交谈 - 应该允许偶尔失败,但我希望异常检查我的错误日志,并且如果此错误似乎过于频繁我需要它变得致命,因为更大的可能是错误的。在例外情况下做这件事似乎是合乎逻辑的地方,你认为这不是吗? – 2011-04-09 04:42:36

+1

@Jesse,这个例外绝对不是处理这类事情的地方。应用程序应该是确定关于不可靠服务器的策略的地方。一个例外基本上是一个错误信息 - 它不应该包含做什么的指示,否则,如果有已知的行为方式,它不是一个例外。 – 2011-04-09 05:00:36

+0

明白了,谢谢!这让我相信我需要重构我的代码结构 – 2011-04-09 14:43:40

1

我可能只是用一个属性去判断一个异常是否是致命的,如果不能将一个特定的异常归类为致命的或可恢复的。

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) 

但是,异常的提出者应该不会告诉侦听器异常是否是致命的。他们可能能够处理被视为致命的异常。例外的目的是声明某些事情是错误的,然后让潜在用户确定他们是否可以从中恢复。