Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SpringMVC:服务层是否应该返回特定于操作的DTO?_Java_Spring_Architecture_Spring Mvc_N Tier Architecture - Fatal编程技术网

Java SpringMVC:服务层是否应该返回特定于操作的DTO?

Java SpringMVC:服务层是否应该返回特定于操作的DTO?,java,spring,architecture,spring-mvc,n-tier-architecture,Java,Spring,Architecture,Spring Mvc,N Tier Architecture,在我的SpringMVC应用程序中,我在表示层中使用DTO来封装服务层中的域模型。DTO被用作弹簧形式的支撑对象 因此,我的服务如下所示: userService.storeUser(NewUserRequestDTO req); 服务层将把DTO转换成->域对象并完成其余的工作 现在我的问题是,当我想从服务中检索一个DTO来执行更新或显示时,我似乎找不到比使用多个方法来查找返回不同DTO更好的方法,例如 EditUserRequestDTO userService.loadUserForEd

在我的SpringMVC应用程序中,我在表示层中使用DTO来封装服务层中的域模型。DTO被用作弹簧形式的支撑对象

因此,我的服务如下所示:

userService.storeUser(NewUserRequestDTO req);
服务层将把DTO转换成->域对象并完成其余的工作

现在我的问题是,当我想从服务中检索一个DTO来执行更新或显示时,我似乎找不到比使用多个方法来查找返回不同DTO更好的方法,例如

EditUserRequestDTO userService.loadUserForEdit(int id);

DisplayUserDTO userService.loadUserForDisplay(int id);
但这种方法有些地方感觉不对劲。也许服务不应该返回EditUserRequestDTO之类的东西,控制器应该负责从专用表单对象组装requestDTO,反之亦然

之所以有单独的DTO,是因为DisplayUserDTO是强类型只读的,而且在类似城市和州的db中,有许多用户属性是查找表中的实体,因此DisplayUserDTO将具有属性的字符串描述,而EditUserRequestDTO将具有支持该属性的id在表单中选择下拉列表

你觉得怎么样


谢谢

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

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

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

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

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

第二次编辑:
说得好。在某些情况下,您可能需要视图可用的有限属性集,即不同的前端和后端开发人员。在回答之前,我应该仔细阅读。若我要做你们想做的事情,我可能会在用户或任何形式的forEdit和forDisplay类上放置单独的方法。这样,您就可以从服务层获取用户,并告诉用户为您提供其自身的有限副本。我想也许这就是我对贫血对象评论的目的。

你应该使用DTO,而不要在MVC层使用ORM!关于这一点,已经提出了许多非常好的问题,例如:


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

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