验证值混淆

Validating values confusion

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

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

我有点困惑,Web 服务的端点接受值,但它不接受负数,我将其声明为 intunsigned int Java,所以现在是在每个规范发出请求之前检查每个规范中值的有效性(因为我已经知道它会失败)还是仅在服务内部检查值的有效性??!!!我认为让每个规范检查它的价值更好,因为这样我有义务使用这个规范的每个服务来处理这个检查,也像这样我可以避免代码重复,如果每个规范不进行检查,并且让服务会为它做这些,检查将在每个服务中重复,在我看来,这不利于代码重用。

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

我对SRP(Single Responsibility Principle)有点疑惑,这样做,每个规范都符合SRP吗??!!!! (我总是对 SRP 有疑问,我无法确切地弄清楚系统中每个 class 的职责是什么)。

这是 Android 的应用程序,我们有意将其也作为 Web 应用程序(因此,我想以正确的方式进行,以最大限度地提高代码重用率)。

如果我用虚假的方式来做,如果有其他更好的方法或任何东西,请让我现在:)

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

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

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

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

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

有时,服务级别验证与控制器中的验证不匹配。想象一下某个项目中的一个场景,普通用户只能输入正值,而管理员也可以输入负值。由于某些业务逻辑原因,两者都不能输入“0”。验证 "is value negative && can current user enter negatives" 将驻留在 Controller 中。验证 "is value zero" 也将驻留在 Controller 中。服务将只有 "throw exception if value is zero" 或只有 "assert value is not zero",因为从它的角度来看,它可以完成请求的正反两方面。

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

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


换句话说:

  • 如果您的规范声明 "user should not be allowed to enter negative values into balance field" - 这将通过正确的消息发送给控制器。
  • 如果您的规范声明 "all clients balances are always positive" - 这将进入服务验证。
  • 如果您的规范声明 "bank webservice only accepts positive values in requests",则此验证的位置是存储库。

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