【问题标题】:Spring MVC: should service layer be returning operation specific DTO's?Spring MVC:服务层是否应该返回特定于操作的 DTO?
【发布时间】:2011-02-07 17:53:40
【问题描述】:

在我的 Spring MVC 应用程序中,我在表示层中使用了 DTO,以便将域模型封装在服务层中。 DTO 被用作弹簧形式的支持对象。

因此我的服务看起来像这样:

userService.storeUser(NewUserRequestDTO req);

服务层将翻译 DTO -> 域对象并完成剩下的工作。

现在我的问题是,当我想从服务中检索 DTO 以执行更新或显示时,我似乎找不到更好的方法来执行此操作,然后使用多种方法进行查找,返回不同的 DTO喜欢...

EditUserRequestDTO userService.loadUserForEdit(int id);

DisplayUserDTO userService.loadUserForDisplay(int id);

但这种方法感觉有些不对劲。也许服务不应该返回像 EditUserRequestDTO 这样的东西,控制器应该负责从专用表单对象组装 requestDTO,反之亦然。

确实有单独的 DTO 的原因是 DisplayUserDTO 是强类型为只读的,并且用户的许多属性是数据库中查找表中的实体(如城市和州),因此 DisplayUserDTO 将具有字符串属性的描述,而 EditUserRequestDTO 将具有支持表单中选择下拉列表的 ID。

你怎么看?

谢谢

【问题讨论】:

    标签: java spring architecture spring-mvc n-tier-architecture


    【解决方案1】:

    我喜欢精简的展示对象。它比构建整个域对象只是为了显示它的几个字段更有效。我使用了类似的模式,但有一点不同。我没有使用 DTO 的编辑版本,而是在视图中使用了域对象。它显着减少了在对象之间来回复制数据的工作。我现在还没有决定是否要这样做,因为我正在使用 JPA 和 Bean Validation Framework 的注释并且混合注释看起来很乱。但我不喜欢仅仅为了将域对象排除在 MVC 层之外而使用 DTO。似乎很多工作没有太多好处。此外,阅读 Fowler 对anemic objects 的看法可能会很有用。它可能并不完全适用,但值得考虑。


    第一次编辑:回复以下评论。

    是的,我喜欢将实际的域对象用于一次对单个对象进行操作的所有页面:编辑、查看、创建等。

    您说您正在获取现有对象并将所需的字段复制到 DTO 中,然后将 DTO 作为模型的一部分传递给模板引擎以获取视图页面(反之亦然)。那给你买什么?对 DTO 的引用并不比对整个域对象的引用轻,并且您需要进行所有额外的属性复制。没有规定说您的模板引擎必须使用对象上的所有方法。

    如果它可以提高效率(无需构建关系图),我会使用一个小的部分域对象,特别是对于搜索结果。但是,如果对象已经存在,那么当您将其粘贴到模型中以呈现页面时,不要担心它有多大或有多复杂。它不会在内存中移动对象。它不会导致模板引擎压力。它只访问它需要的方法,而忽略其余的。


    第二次编辑: 好点子。在某些情况下,您可能希望视图可以使用一组有限的属性(即不同的前端和后端开发人员)。在回复之前,我应该更仔细地阅读。如果我打算做你想做的事,我可能会在 forEdit() 和 forDisplay() 形式的 User(或任何类)上放置单独的方法。这样你就可以从服务层获取用户并告诉用户给你使用有限的副本。我想也许这就是我对贫血对象评论的目的。

    【讨论】:

    • 感谢您的回复。如果您将域对象用于编辑操作,那么您是否也将域对象用于新操作和其他所有操作,为什么只用于编辑?就我而言,我被一个贫血的域对象困住了,对此无能为力。使用 DTO 的原因是我的域对象很复杂,其中包含许多我的视图不需要的关系和属性。
    • 感谢 GMK,我之所以考虑这样做并不是因为它在系统上更轻。我认为我想做的事情是有正当理由的。的确,我不必从域对象中使用我不需要的任何东西,但是有时使用该对象来获取我需要的东西可能很困难,还有一个安全问题,因为视图可以访问它不应该访问的字段有,锁定对象可能同样麻烦。
    【解决方案2】:

    您应该在 MVC 层中使用 DTO 而永远不要使用 ORM!在这方面已经有很多非常好的问题,例如:Why should I isolate my domain entities from my presentation layer?

    但要补充这个问题,您应该将它们分开,以帮助防止 ORM 被绑定在帖子上,因为有人可能会添加额外的字段并导致各种需要不必要的额外验证的混乱。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2011-07-01
      • 2011-06-08
      相关资源
      最近更新 更多