BL 服务:异常还是方法结果?
最好的方法是什么?为什么?
V1:
try
{
var service = IoC.Resolve<IMyBLService>();
service.Do();
}
catch(BLException ex)
{
//Handle Exception
}
V2:
var service = IoC.Resolve<IMyBLService>();
var result = service.Do();
if (!result.Success)
{
//Handle exception
}
What is the best way and why?
V1:
try
{
var service = IoC.Resolve<IMyBLService>();
service.Do();
}
catch(BLException ex)
{
//Handle Exception
}
V2:
var service = IoC.Resolve<IMyBLService>();
var result = service.Do();
if (!result.Success)
{
//Handle exception
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为例外更好。我认为 DDD 代码首先是优秀的面向对象代码。关于在 OO 语言中使用异常与返回代码的争论已经基本结束。在 DDD 上下文中,我看到使用异常的以下好处:
它们强制调用代码来处理它们。异常不要让客户端代码忘记错误。调用代码可能只是忘记检查
result.Success
。在我看来,抛出和处理代码都更具可读性、自然性和简洁性。没有“ifs”,没有多个 return 语句。无需将您的域服务弯曲为“操作”。
在我看来,DDD 就是使用简单的 OO 语言来表达特定的业务问题并尽可能地将基础设施排除在外。创建“OperationResult”类对我来说似乎过于基础化和通用化,尤其是当语言已经支持异常时。
域对象无论如何都会抛出异常,即使它只是为了检查参数。因此,对域服务使用相同的机制似乎很自然。
也许也值得看看设计本身,也许有一种方法可以一开始就不会进入错误状态?例如,可以通过使用 值对象 而不是原始字符串来消除整个“验证”错误条件整数。
DDD 是一种方法、一套指南,因此不存在“正确”的方法。 书从未直接提及此问题,但代码片段和示例项目中的代码使用了异常。
Exceptions are better in my opinion. I think that DDD code is first and foremost good object oriented code. And the debate about using exceptions vs return codes in OO languages is mostly over. In DDD context I see following benefits of using exceptions:
they force calling code to handle them. Exception don't let client code forget about the error. Calling code can simply forget to check for
result.Success
.both throwing and handling code is more readable, natural and brief in my opinion. No 'ifs', no multiple return statements. No need to bend your Domain services to be exposed as 'operations'.
DDD in my opinion is all about using plain OO language to express specific business problems and keeping infrastructure out as much as possible. Creating 'OperationResult' class(es) seems too infrastructural and generic to me especially when language already supports exceptions.
Domain objects will throw exceptions anyway, even if its only for checking arguments. So it seems natural to use the same mechanism for domain services.
It may also be worth looking at the design itself, maybe there is a way to not get into error state in the first place? For example the whole class of 'validation' error conditions can be eliminated by using Value Objects instead of primitive strings and ints.
DDD is an approach, a set of guidelines so there is no 'right' way. The book never mentions this issue directly but the code in snippets and sample project use exceptions.
首先,
IoC.Resolve()
实际上是 IoC 容器的一种非常糟糕的用法,您应该注入依赖项,而不是解析它们。我知道这不是问题的重点,但值得一提。至于异常与方法结果,这取决于情况。处理此问题的标准方法是使用异常,但是在某些情况下,返回结果会更干净且不那么麻烦。例如,我经常使用操作结果,因为我对从 SOA 层抛出非域相关异常有非常具体的要求,因此我需要捕获与域相关的异常来创建一个新异常。这不符合逻辑,不可读,而且影响了性能,因此我们转而采用带有一点基础设施糖的结果。
另一件值得一提的事情是,当您需要运行并返回所有验证的结果而不在第一个无效规则时停止时,异常往往是 PITA。
First of all, the
IoC.Resolve<IMyBLService>()
is actually a very bad usage of IoC container, you should inject your dependencies, not resolve them. I know that's not the point of the question, but it's worth mentioning.As for Exception vs method result, it depends. The standard way to handle this is with Exceptions, however there are scenarios where it is cleaner and less cumbersome to return result instead. For example, I very often use operation results, because I have a very specific requirements for throwing non-domain related exceptions out of my SOA layer, so I would need to catch a domain-related exception just to create a new one. It wasn't logical, it wasn't readable, it affected performance, so we switched to results with a little bit of infrastructural sugar.
Another thing worth mentioning is that Exceptions tend to be a PITA when you need to run and return results of all your validation, without braking on first invalid rule.