【问题标题】:Validating values confusion验证值混淆
【发布时间】:2016-04-06 14:41:08
【问题描述】:

我正在使用存储库模式与规范模式相结合来与服务网络交互(我更喜欢存储库而不是 DAO):正如此链接所示:http://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/

用户界面与控制器交互,控制器与服务交互,服务与存储库交互,规范为服务web做CRUD操作,可以说这是应用的全局架构,分层架构。

我很困惑,网络服务的端点接受值,但它不接受负数,我将它声明为 int 并且在 Java 中没有 unsigned int,所以现在它是最好在每个规范发出请求之前检查每个规范中值的有效性(因为我已经知道它会失败),或者只在服务内部??!!!我认为让每个规范检查它的价值更好,因为这样我有义务使用这个规范的每个服务来处理这个检查,同样我可以避免代码重复,如果每个规范不做检查,让该服务为它执行此操作,检查将在每个服务中重复,在我看来,这不利于代码重用。

将验证放在存储库中是否很好,如果测试失败会引发异常,服务将不会捕获它,并让控制器捕获它以通知用户他输入的内容。

我对 SRP(单一责任原则)有点困惑,通过这样做,每个规范都符合 SRP 吗??!!!! (我总是对 SRP 有疑问,我无法确切地弄清楚系统中每个类的职责是什么)。

这是一个适用于 Android 的应用程序,我们有意将其也作为 Web 应用程序(所以,我想以正确的方式来做,以最大限度地重用代码)。

如果我以虚假的方式进行操作,如果有其他更好的方法或其他方法,请让我现在:)

【问题讨论】:

    标签: java validation repository-pattern single-responsibility-principle


    【解决方案1】:

    您可以在任何地方进行验证,但是,根据您放置验证的位置,验证需要不同的角色:

    控制器是面向用户的。因此,他们应该验证用户输入并呈现一些可读错误。根据您使用的框架,这可能是单独的验证器或绑定器或其他任何东西的任务,但它都与控制器密切相关。

    在任何情况下,用户数据的任何验证都应该在控制器将请求转发到服务之前处理。如果您需要禁止输入“-1” - 它应该在这里。如果人们在文本字段中输入“abc” - 再次在这里。以此类推。

    服务是面向领域的。他们应该验证给定的任务是否可以用给定的数据完成。但是,如果不是,它们应该使用某种断言调用快速失败或抛出运行时异常。他们不应该提供关于失败原因的好错误列表(如果仅用于审计目的)。他们提供的任何数据都应该已经被以前的实体(控制器、验证器等)覆盖。服务唯一关心的事情 - 如果业务规则允许他们要求的操作。

    如果服务层中的验证失败(抛出异常) - 这表明您在控制器中错过了一些验证。

    有时,服务级别验证与控制器中的验证不匹配。想象在某个项目中,普通用户只允许输入正值,而管理员也可以输入负值。由于某些业务逻辑原因,两者都不能输入“0”。验证“是负值 && 当前用户是否可以输入负数”将驻留在控制器中。验证“为零值”也将驻留在 Controller 中。服务只会有“如果值为零则抛出异常”或只是“断言值不为零”,因为从它的角度来看,它可以通过正面和负面的方式完成请求。

    存储库/规范是面向数据源的。因此,这些可以添加一些与发送请求本身相关的断言。如果已知数据源不接受零 - 此层可以预先验证它并抛出异常,以防它被赋予查询零的任务。

    如果存储库层中的验证失败(抛出异常) - 这表明您在服务或控制器中错过了一些验证。


    换句话说:

    • 如果您的规范声明“不应允许用户在余额字段中输入负值” - 这将通过适当的消息发送给控制器。
    • 如果您的规范声明“所有客户端余额始终为正数” - 这将进入服务验证。
    • 如果您的规范声明“银行 Web 服务仅接受请求中的正值”,则此验证的位置是存储库。

    因此,无论您的场景是什么,请考虑哪些约束是正确的,并适当地组织您的验证。

    【讨论】:

    • 非常感谢,以非常好的方式解释,非常有用,现在一切都清楚了,我会将您的答案添加为参考,再次感谢您:)
    猜你喜欢
    • 2020-10-10
    • 1970-01-01
    • 2022-08-13
    • 2018-06-04
    • 2019-05-29
    • 2011-03-06
    • 2011-06-09
    • 2014-04-19
    • 2012-11-24
    相关资源
    最近更新 更多