尝试重构一些代码。我看到一些创建DTO对象的类正在服务层中传递,后来由@RestController返回。据我所知,最好只在控制器中构建数据传输对象并将它们传递给视图,尤其是当我们使用带有get和set值的WrapperDTO<T>
之类的东西时。当我们使用复杂对象或简单数据类型构建WrapperDTO时,可能存在差异。所有的oppinions将非常感激。
答案 0 :(得分:6)
DTO可用于在应用程序的不同层之间传输数据:DAO,服务,外观,控制器。根据我的经验,DTO是一个自以为是的主题。
在我看来,转换越晚越好,如果不需要转换则更好。通常,后者位于应用程序边界。 DTO不是免费的,它涉及映射及其支持。因此,当存在域模型不匹配或模型技术不匹配时,DTO将是有意义的。有关详细信息,请查看LocalDTO article and the associated link。
如果我专注于服务 - &gt; facade - &gt; controller 图层:
服务:他们正在做服务,他们可能会互相打电话进行处理。如果您的域模型在服务边界service => facade
内保持一致,那么将结果转换为DTO为时尚早。
Facades:他们可能会协调服务并转换输入/输出。在我看来,它将是转换到DTO或从DTO转换的正确位置。但只有在需要时才是这样。因为您的域模型必须在此边界内进行转换(过滤字段,聚合......)
网关/控制器:它们位于应用程序边界。他们的逻辑很简单,简化为边界逻辑。外观和控制器之间的关系通常是one <-> one
。 ***
合并外墙和控制器通常是有意义的
因此,在我看来,你的第一个提案更适合,例如。 UserController....
。最重要的是保持务实。
答案 1 :(得分:2)
我想说在服务层创建DTO会更好。
控制器不得知道业务逻辑细节。例如。我们需要返回用户信息,但必须排除某些字段(密码等)。这些字段存在于用户实体中,但必须从DTO中删除。
我们在Controller上获得SomePaginationDTO
的另一个案例,我们仍然需要将DTO传递给服务来解析过滤器,应用排序,限制结果等。所有逻辑都是服务责任的一部分。所以我会将SomePaginationDTO
传递给服务。
答案 2 :(得分:0)
我想说没有规范的正确方法可以做到这一点。这取决于DTO的用途。
我为自己找到了一个简单的规则,即在服务级别使用DTO的位置以及不在何处使用:如果服务级别只有一个客户端,我会在服务级别使用DTO。如果有两个或更多客户端,最好不要在服务级别使用DTO。
让我更详细地解释一下:
基本上很明显,不将DTO纳入服务级别需要更多的努力。因此,如果只有一个客户端,我会保持简单,并使用DTO作为服务方法的返回类型。
如果服务的客户端多于一个,则客户端最有可能需要不同的DTO(例如,我希望对象的json
和csv
表示。在这种情况下,我不会从服务中返回DTO。否则,我需要为每个DTO或不同的服务方法等提供不同的服务。
注意:我不是说如果你不在服务级别使用DTO,你必须将转换逻辑移动到控制器级别。我仍然认为控制器级别必须尽可能简单。您可能在控制器和服务之间有一些中间转换级别 - 不舒服,但它比使用多个服务要好得多。
答案 3 :(得分:-1)
作为其他问题的一部分,我找到了一个很好的答案。当然这个/我的答案不参与赏金。这只是一个解释如何实现事物的灵感。所以看看:
您对该设计有何看法?是否适用于众所周知的春季mvc?