违反业务规则是否应该引发异常?
违反业务规则是否应该引发异常?
Should a business rule violation throw an exception?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
违反业务规则是否应该引发异常?
Should a business rule violation throw an exception?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(14)
不。它是程序中正常条件处理逻辑的一部分(通常只是用户错误的一种伪装形式)。
No. It's part of normal conditional-handling logic in the program (and often just a disguised form of user error).
IMO,这取决于业务规则是什么。 我敢说“通常不会”,但我会根据具体情况来看待。 我认为没有任何一个答案,因为不同的业务规则可能会保证这一点,而其他规则可能不会。
It depends on what the business rule is, IMO. I would venture to say "not usually" but I'd view it on a case-by-case basis. I don't think there is any one answer, as different business rules might warrant it while others might not.
首先,引用《应用 Microsoft .NET Framework 编程》(第 402 页)第 18 章中的一些内容杰弗里·里克特:
如果我从您的问题中正确推断出业务规则违规将是超出特定范围(例如)的数据,那么您可以按照 @ahockley 的建议使用条件来处理此错误。 根据 Richter 对异常的定义,如果您的代码无法从您正在使用的任何存储库检索业务规则,则应适当使用异常。 能够检索业务规则将是该接口具有的合理隐式假设,因此如果违反此假设,则应抛出异常。
Richter 的第一句话(异常!=错误)的一个很好的例子是 ThreadAbortException。 如果调用 Response.Redirect(url)(在 ASP.NET 中),即使重定向成功,也会引发 ThreadAbortException。 为什么? ASP.NET 页面执行的隐含假设是页面将完全执行。 Response.Redirect(url) 违反了这个假设,因此出现异常。
First, a couple of quotes from chapter 18 of Applied Microsoft .NET Framework Programming (page 402) by Jeffrey Richter:
If I'm inferring correctly from your question that a business rule violation would be data that falls outside a certain range (for example), this is an error that you could handle with a conditional as @ahockley suggested. Based on the definition of an exception from Richter, the appropriate use of an exception would be if your code wasn't able to retrieve a business rule from whatever repository you're using. Being able to retrieve a business rule would be a reasonable implicit assumption for that interface to have, so an exception should be thrown if this assumption was violated.
One good example of Richter's first quote (exception != error) is the ThreadAbortException. If you call Response.Redirect(url) (in ASP.NET), a ThreadAbortException is thrown even though the redirect succeeds. Why? The implicit assumption of ASP.NET page execution is that a page will execute completely. Response.Redirect(url) violates this assumption, hence the exception.
由于我进行验证的方式以及对 ORM 的 LINQtoSQL 的使用,是的。 如果实体在 OnValidate 方法期间未能对业务规则进行验证,则通知调用代码的唯一方法是抛出异常。 在本例中,我抛出一个自定义 DataValidationException。 在实体的分部类实现中使用 OnValidate 方法挂钩使我可以在更新/插入时强制验证,以便仅将有效数据保存到数据库中。
编辑我应该明确指出,我通常在客户端对用户输入进行验证,因此持久层验证通常更保险,而且很少失败(如果有的话)。 我不将客户端验证作为异常处理,而是使用条件逻辑。
Because of the way I do my validation and my use of LINQtoSQL for ORM, yes. If an entity fails validation on a business rule during the OnValidate method, the only way to notify the calling code is to throw an Exception. In this case, I throw a custom DataValidationException. Using the OnValidate method hook in a partial class implementation of the entity makes it possible for me to enforce validation on update/insert so only valid data gets saved to the database.
EDIT I should make it clear that I typically do validation of user input at the client so the persistence layer validation is typically more insurance and rarely, if ever, fails. I don't handle the client-side validation as exceptions, but rather with conditional logic.
例如,您的意思是,一个值应该在 0-99 范围内,但不知何故最终变成了 105?
如果它来自用户,那就是验证问题。 是否使用异常处理取决于您的语言的习惯用法。
如果它来自您的数据存储,那么是的,抛出异常似乎是合理的。 这意味着您有坏数据,您需要弄清楚它是如何到达那里并防止它再次发生。
Do you mean, for example, that a value is supposed to be in the range 0-99 but somehow ended up being 105?
If it's coming from the user it's a matter of validation. Whether it is handled using exceptions or not depends on the idioms of your language.
If it's coming from your data store then yes, it seems reasonable to throw an exception. It means you have bad data and you need to figure out how it got there and prevent it from happening again.
不
违反业务规则是一个业务问题,而例外是一个技术问题。 系统应将违反业务规则视为正常操作,并应对其进行编程响应,而不是例外。
No
Violating a business rule is a BUSINESS issue where an exception is a technical one. Violating a business rule is something that the system should regard as normal operation and for which it should have a programmed response, not an exception.
作为大多数答案的替代视图......
从业务逻辑中抛出异常可能很有用,特别是如果它们是由验证失败引起的。 如果您期待一个对象,但得到一个空值,则表明某些问题已经逃避了用户界面(或其他界面)中的检测。 此时抛出异常可能是完全有效的。 事实上,当存在多个接口时,您可能决定将这种类型的验证放置在业务逻辑中。
在某些语言/框架(我认为是.NET)中抛出异常可能代价高昂,但这不应该立即让您担心。 顾名思义,这确实意味着它们用于特殊情况,而不是作为程序标准流程的一部分。 您当然不应该仅仅为了退出方法而抛出异常。 您还应该在可能的情况下考虑优雅的恢复,其中可能不包括抛出异常。
所以,总结一下...这取决于...
As an alternative view to most of the answers...
It can be useful to throw exceptions from the business logic, particularly if they are cuased by a failure in validation. If you are expecting an object and you get a null, it suggests that some problem has evaded detection in the user interface (or other interface). It may be completely valid to throw exceptions at this point. Indeed, you may decide to place this type of validation in the business logic when there are multiple interfaces.
Throwing exceptions in some languages / frameworks (I am thinking .NET) can be costly but this should not immediately worry you. It does mean that, at the name suggests, they are used for exceptional circumstances and not as part of the standard flow of a program. You certainly shouldn't throw an exception just to exit a method. You should also consider a graceful recovery where possible that may not include throwing an exception.
So, summing up... It depends...
我会说通常不会,但我不认为你可以说永远不会。
例如,这取决于谁/什么正在处理失败的规则。 如果它是用户界面/用户,那么我将使用条件逻辑来适当地处理故障。 然而,如果是业务规则失败,例如,将任何错误记录到事件日志中的匿名流程,该事件日志将由技术资源进行监控,则异常可能是适当的。 在后一种情况下,适当命名的异常与格式良好的消息一样有用。
I would say not normally but I don't think you can say never.
For instance it depends on who/what is handling of the failed rule. If it is a user interface/user then I would use conditional logic to deal with the failure appropriately. However if it is a business rule failure in, for instance, a faceless process that logs any errors to an event log which will be monitored by for a technical resource then an exception may be just as appropriate. In this later case an appropriately named exception can be just as helpful as a nicely formatted message.
业务规则可能会引发异常,但实际上不应该。
如果您有其他方法来传达有关常见且可预测的验证错误的信息,则应该使用它。
Business rules could throw exception but they shouldn't.
If you have another way to communicate information about common and predictable validation error, you should use it.
抛出异常可能需要大量计算,它们超出了正常范围。 例如,在 .net 中,您有递增的性能计数器 - 这是一项重量级活动,因此除了简单的条件之外,您不想做任何事情。
Throwing exceptions can be computationally intensive, they are outside of the norm. For example in .net you have performance counters that are incremented - that is a heavyweight acitivty and so not something you would want to do instead of a simple conditional.
这实际上取决于它是什么以及它在哪里。
如果是来自用户的一些数据,那么正如 Levand 所说,这就是验证问题。 验证可能会成功,也可能会失败,这两种情况都是预期的选项,并具有明确的进一步行动方案。
如果是方法执行错误之类的问题,那么在造成更多损害(例如在数据库中产生不一致)之前抛出异常并立即停止可能是更好的主意。
这通常是视角和应用程序设计的问题。
It really depends on what it is and where it is.
If it's some data coming from the user then as levand said it's a matter of validation. Validation can turn up both successful and failed, both are expected options with clear further action scenarios.
If it's something like method execution errors it could be a better idea to throw an exception and stop right there before more harm is done (such as producing inconsistencies in the database).
It is often a matter of perspective and your application design.
通常我将条件放在实现的规范对象中,
因此您可以毫无例外地检查条件。
如果代码中的某个位置应事先验证规范,则可以抛出异常,因为这是函数的先决条件。
例如,如果您的实体在持久化之前必须处于特定状态,则在未验证规范时抛出异常,但在持久化之前使用规范,以便不会发生异常。
Usualy I put the condition in a Specification object that implements
So you can check the condition without exception.
If there is a place in your code where the specification should be verified beforehand, you can throw an exception because this is a prerequisit of you function.
For instance if your entity must be in a specific state before persistance, throw an exception when the specification is not verified, but use the specification before persisting so that the exception does not happen.
业务规则不应引发异常,除非它们用于验证某些 API 的参数(即:检查请求有效性)或在单元测试中(即:使用业务规则简化 .NET 单元测试)。
不过,通常业务规则会向验证范围输出错误和警告消息。
Business rules should not throw an exception, unless they are used to validate parameters of some API (i.e.: checking requests validity) or in unit tests (i.e.: using business rules to simplify .NET unit tests).
Generally business rules output error and warning messages to the validation scope, though.
这本书的维基中有很好的指导 97每个项目经理都应该知道的事情,特别是区分业务一章技术例外。
因此,如果您的编程语言支持它,最好的办法是创建自定义异常类,以便它们的工作流程和处理可以与技术异常不同。
There is good guidance in the wiki for the book 97 Things Every Project Manager Should Know, in particular in the chapter Distinguish Business Exceptions from Technical.
So, if your programming language supports it, the best thing is to create custom exception classes so the their workflow and handling can be different from technical exceptions.