是否建议从验证方法中抛出异常,如:
ValidateDates();
ValidateCargoDetails();
除此之外:是否经常使用强大的验证设计模式?
答案 0 :(得分:29)
我建议返回包含ValidationFailures的ValidationResult对象。 您不应该将异常用作逻辑编码的一部分。异常是例外
答案 1 :(得分:15)
我通常使用visitor pattern
来验证输入;将所有错误累积到列表或其他内容以显示用户。逻辑就像检查列表中的验证错误一样,如果找到,则通知用户,否则很好。
IMO,验证错误不是特例,因此不应该像一个人那样处理。
答案 2 :(得分:9)
我想说这一切都取决于您进行验证的内容/方式。但是在一天结束时,开发人员总是可以选择忽略返回的结果(这是他们的问题),他们不能在不编写显式代码的情况下忽略异常。
答案 3 :(得分:3)
抛出异常必须不用于控制应用程序的流程。顾名思义,它发生在例外情况下,而验证通常会失败。它们也昂贵并影响性能。
我会返回布尔加上一个字符串。
答案 4 :(得分:3)
很多情况取决于验证失败的异常程度是多么重要。
如果您的验证失败是罕见的,严重的或致命的,我会使用Exceptions甚至AssertionErrors。大多数解析器使用异常,这表明无法继续处理。
如果您的验证失败是在正常操作下进行的,并且未表明您无法继续处理,我建议您使用访问者模式或返回问题列表(可能为空)
答案 5 :(得分:1)
我只是想将这张照片带入图片,RADZSERG在博客上的回答:Why throwing exceptions is better than returning error codes。
简而言之-我们不需要限制自己使用布尔值作为返回类型...
我不是说我们应该使用或不使用Exception
但是关于那篇特定的文章–您在开始时构建了错误的代码,然后试图使其变得更好。在一开始就构建良好的代码,并解释为什么我们使用异常时会更好。 这是我的例子
class TooManyLoginAttempts extends ValidationError{} if ($hasTooManyLoginAttempts) { return new TooManyLoginAttempts() } ... $validationResult = $this->validate(); if ($validationResult instanceof ValidationError) { $this->errorLogger->log($validationResult->getMessage()); }
它也解决了所有描述的问题
–没有魔术数字
–我们正在解决在整个应用程序中包含错误代码的问题
–我的代码短得多,并且遵循开闭原则
我来自这里:Is it a good practice to throw an exception on Validate() methods or better to return bool value?,它已被锁定。
答案 6 :(得分:0)
输入无效数据的用户是异常的定义。在为解决方案编写业务需求时,始终将非错误路径编写为主流和错误路径作为异常路径。使用例外验证是完全可以接受的。使用异常进行验证还允许您按顺序处理错误处理顺序的优先顺序,并根据您在架构堆栈中的级别来区别地处理错误(描述错误的字符串在数据访问层中几乎没用)。 / p>
答案 7 :(得分:0)
说实话,我在所有这一切上都处于戒备状态。有时我也在构建访问者模式,但确实感觉到我只是在重新实现Exception。
对于访问者模式,我绝对不喜欢的是,如果您的六个层次很深,并且您发现需要中断,则必须检查以上每个层次的结果。
这意味着很多样板代码实际上可能会引入错误。
示例
如果您检查了A
-它不生效,但是代码继续检查实际上取决于正确初始化的B
的{{1}}怎么办?在复杂的验证逻辑中,这可能发生在许多不同的路径上。容易出错。
另一方面,我使用了(自定义)A
,并且没有遇到任何重大问题。您遇到了未验证的内容,并确保将跳过所有其他验证逻辑。这是简化代码的一大胜利。
“不得使用抛出异常来控制应用程序的流程。” -对于我同意的99%的其他情况,但在我看来,继续验证逻辑在教条上,而不是在实用主义上。
关于性能: 性能原因不是用户输入的验证逻辑中有99%的问题,因为这几乎从来不会在紧缩循环中完成。
摘要::我建议忽略“异常是针对异常事物的” 教条,创建(自定义!)在顶层抛出并捕获的异常,看看是否它为你工作。对我来说确实如此。