我想创建一个带有常见异常处理模式的抽象类:
public abstract class Widget
{
public IFoo CreateFoo()
{
try
{
CreateFooUnsafe();
}
catch(Exception ex)
{
throw new WidgetException(ex, moreData, evenMoar);
}
}
protected abstract IFoo CreateFooUnsafe();
}
目的是在所有派生对象之间建立标准的异常处理模式。不应期望抽象CreateFooUnsafe()
方法包含任何异常处理。实现可能只有一行return new Foo(...)
我想知道的是,是否存在与此模式相关的任何标准命名约定,特别是在需要抛出异常代码的情况下?
以上名称似乎有点合适,但并非完全没有气味。
答案 0 :(得分:4)
这似乎是template method pattern 的一个例子。
模板方法是一种模式,可以通过使用公共非虚函数实现某些过度行为来表达许多面向对象的语言,以及受保护的虚拟(或抽象)方法来补充子类中的具体行为
在您的示例中,您使用模板方法捕获从内部实现中冒出的所有异常,并将它们包装在自定义异常类型中。关于这个特定实践,我要做的一个评论是只有添加允许调用代码才能更好地处理异常的上下文信息才有意义。否则,最好只允许源异常传播出来。
答案 1 :(得分:1)
上面的代码中有几种不同的模式。除其他外,它看起来有点像Abstract Factory模式,即,你有一个抽象类,它实现了一个返回实现特定接口的具体对象的工厂方法。
至于这种异常处理是否是一个好主意 - 我倾向于同意其他人的意见,我通常不会在这种方法中看到很多价值。我看到你正在尝试做什么,即提供一种异常处理,就像CreateFoo()返回单个接口(IFoo)一样。但我能想到的唯一好处是,如果您在WidgetException中提供一些有趣且相关的故障排除信息(例如,某些数据库或服务连接字符串,或堆栈跟踪周围的某些特殊处理逻辑)。如果您只是包装原始异常以便客户端可以处理WidgetException,那么您还没有真正完成任务:它们可以轻松地处理基本Exception类型。
答案 2 :(得分:1)
简短的回答是否定的。
模板模式中没有约定来指定什么类型以及何时抛出异常。根据MSDN,这种信息包含在文档的某些部分中。使用C#和XML注释,您可以轻松生成此类文档。
我的印象是,可能存在一个命名约定,模板模式本身没有任何引用异常处理。据我了解,命名可能如下所示:
public abstract class Widget
{
public void PerformAction()
{
this.PerformActionImpl();
}
protected virtual void PerformActionImpl(){}
}
Impl是“实施”的简写。就个人而言,我不喜欢这种命名风格,所以不要使用它,但我确信我已经在某个地方读到了半权威,这就是“做”它的方法。
我不会在你的情况下使用任何这个,但是你真正想要的是Factory或AbstractFactory。
...
关于你的异常查询,在我看来代码有点内在,我不同意其他一些注释,具体取决于你的情况。
Wrap and throw是一种完全有效的异常处理技术。
异常本身类型提供的附加上下文可能足以将异常路由到适当的处理程序。即你已经将一个Exception转换为一个WidgetException,人们期望它在你的应用程序中有上下文。所以这可能已经足够好了。
在你完成包装的地方我不同意。
我会做醒目的包装,并从虚拟方法,只有子类都将有什么它做知道异常是否确实是WidgetException不够了解的子类实现内投掷的因此,包裹,扔掉或稍微多毛的东西应该传播。
现在的代码是对异常原因进行一些大量的假设,从这个意义上说,任何使用自定义异常都是无用的。即现在一切都是WidgetException。
因此,虽然我认为单独的类型足以将异常置于语境中,但我不相信代码会在正确的位置做出决定。我理解你所选择的实现背后的动机,因为它似乎是一个非常美味的捷径,“所有知道基类的神话”,但你宣称它是抽象的这一事实应该提供一个重要的线索,该类是打算在设计上无知。
因此,对于异常处理的横切关注点,我认为你不应该为了让你的生活变得更容易,而是一个抽象所有guff的框架。
例如企业库。