Spring MVC:服务层是否应该返回操作特定的 DTO?

发布于 2024-08-28 23:54:16 字数 701 浏览 2 评论 0原文

在我的 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。

你怎么认为?

谢谢

In my Spring MVC application I am using DTO in the presentation layer in order to encapsulate the domain model in the service layer. The DTO's are being used as the spring form backing objects.

hence my services look something like this:

userService.storeUser(NewUserRequestDTO req);

The service layer will translate DTO -> Domain object and do the rest of the work.

Now my problem is that when I want to retrieve a DTO from the service to perform say an Update or Display I can't seem to find a better way to do it then to have multiple methods for the lookup that return different DTO's like...

EditUserRequestDTO userService.loadUserForEdit(int id);

DisplayUserDTO userService.loadUserForDisplay(int id);

but something does not feel right about this approach. Perhaps the service should not return things like EditUserRequestDTO and the controller should be responsible of assembling a requestDTO from a dedicated form object and vice versa.

The reason do have separate DTO's is that DisplayUserDTO is strongly typed to be read only and also there are many properties of user that are entities from a lookup table in the db (like city and state) so the DisplayUserDTO would have the string description of the properties while the EditUserRequestDTO will have the id's that will back the select drop down lists in the forms.

What do you think?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱情眠于流年 2024-09-04 23:54:16

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


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

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

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

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


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

I like the stripped down display objects. It's more efficient than building the whole domain object just to display a few fields of it. I have used a similar pattern with one difference. Instead of using an edit version of a DTO, I just used the domain object in the view. It significantly reduced the work of copying data back and forth between objects. I haven't decided if I want to do that now, since I'm using the annotations for JPA and the Bean Validation Framework and mixing the annotations looks messy. But I'm not fond of using DTOs for the sole purpose of keeping domain objects out of the MVC layer. It seems like a lot of work for not much benefit. Also, it might be useful to read Fowler's take on anemic objects. It may not apply exactly, but it's worth thinking about.


1st Edit: reply to below comment.

Yes, I like to use the actual domain objects for all the pages that operate on a single object at a time: edit, view, create, etc.

You said you are taking an existing object and copying the fields you need into a DTO and then passing the DTO as part of the model to your templating engine for a view page (or vice-versa for a create). What does that buy you? The ref to the DTO doesn't weigh any less than the ref to the full domain object, and you have all the extra attribute copying to do. There's no rule that says your templating engine has to use every method on your object.

I would use a small partial domain object if it improves efficiency (no relationship graphs to build), especially for the results of a search. But if the object already exists don't worry about how big or complex it is when you are sticking it in the model to render a page. It doesn't move the object around in memory. It doesn't cause the templating engine stress. It just accesses the methods it needs and ignores the rest.


2nd edit:
Good point. There are situations where you would want a limited set of properties available to the view (ie. different front-end and back-end developers). I should read more carefully before replying. If I were going to do what you want I would probably put separate methods on User (or whatever class) of the form forEdit() and forDisplay(). That way you could just get User from the service layer and tell User to give you the use limited copies of itself. I think maybe that's what I was reaching for with the anemic objects comment.

沧桑㈠ 2024-09-04 23:54:16

您应该在 MVC 层中使用 DTO 而不是 ORM!对此已经提出了许多非常好的问题,例如以下问题: 为什么我应该将域实体与表示层隔离?

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

You should use a DTO and never an ORM in the MVC layer! There are a number of really good questions already asked on this, such as the following: Why should I isolate my domain entities from my presentation layer?

But to add to that question, you should separate them to help prevent the ORM being bound on a post as the potential is there for someone to add an extra field and cause all kinds of mayhem requiring unnecessary extra validation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文