验证值混淆

时间:2016-04-06 14:41:09

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

我使用Repository模式与Specification Pattern结合与服务Web交互(我更喜欢存储库而不是DAO):正如此链接建议的那样:http://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/

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

我很困惑,网络服务的端点接受了值,但它不接受负数,我将其声明为int并且那里有在Java中不是unsigned int,所以现在在规范发出请求之前检查每个规范中的值的有效性是好的(因为我已经知道它会失败),或者只是在服务内部?!! !我认为让每个规范检查它的价值更好,因为就像我要求使用这个规范的每个服务来处理这个检查,也就像我可以逃避代码重复,如果每个规范deosn不进行检查,让服务为它做,检查将在每个服务中重复,在我看来,这对代码重用是不利的。

在内部存储库中验证是否合适,如果测试faillure会引发异常,服务将无法捕获它,并让控制器捕获它以通知用户他所拥有的内容。

我对SRP(单一责任原则)感到困惑,通过这样做,每个规范是否符合SRP?!!!! (我总是遇到SRP问题,我无法准确确定系统中每个类的职责)。

这是Android的一个应用程序,我们有把它也作为Web应用程序(因此,我希望以正确的方式进行,以最大化代码重用)。

如果我以虚假的方式做这件事,如果还有其他更好的方式,那么现在就让我吧:)

1 个答案:

答案 0 :(得分:2)

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

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

在任何情况下,在完美的世界中,任何对用户数据的验证都应该在控制器将请求转发给服务之前进行处理。如果您不允许输入“-1” - 它应该在这里。如果人在文本字段中输入“abc” - 再次在这里。等等。

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

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

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

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

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

换句话说:

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

因此,无论您的情况如何,请考虑哪些约束是正确的,并适当地组织验证。