我正在遵循Controller、Service和Repository模式,我只是想知道DTO从何而来。
控制器应该只接收DTO吗?我的理解是,你不想让外界知道潜在的领域模型?
从域模型到DTO的转换是否应该发生在控制器或服务层?
发布于 2020-04-19 12:20:28
在使用Spring和交互式UI进行编程的今天,web应用程序实际上有4层:
用户界面层( Controller,JavaScript)
@Controller
@Service
@Repository
注释的Spring组件)
每次这些层中的一个与底层交互时,它们都需要发送/接收数据(通常是POJO),以便在层间传输数据。这些POJO是DTO,也就是数据传输对象。
只应在层间使用DTO,它们不一定相同,例如,服务层可以将业务逻辑应用于从数据访问层接收的DTO,因此服务层API的DTO不同于数据访问层API。类似地,控制器可以重新排列数据以准备它的表示(分组、摘要、.),因此发送到web浏览器的数据不同于从服务层接收的数据。
在完全抽象的情况下,数据访问层的API不应反映数据访问技术,即它是否使用JDBC、JPA、NoSQL、web服务或其他存储/检索数据的方法。这意味着实体类不应该使它在数据访问层之外。
大多数项目不需要那样的抽象级别,因此DTO通常是一个实体类,并从数据访问层一直流到Controller,在Controller中,它被View使用,或者被发送到web浏览器,编码为JSON。
这取决于项目的规模和复杂性。项目越大,使每个层尽可能抽象/独立就变得越重要。
发布于 2020-04-19 11:22:18
不同的组织遵循不同的模式。这取决于你所遵循的模式。根据我个人的经验,我遵循下面的架构图。
根据上面的图表,DTO到实体对话(反之亦然)只在服务层内。
发布于 2020-04-19 11:17:13
一个简单的答案可能是: DTO (如果您需要DTO,请参阅下面)是允许您将特定信息传输到其他地方的东西。这是Controller/Adapter/Repository/无论您如何称呼它的任务。适配器的任务是从外部(系统边界之外)获取信息,并将这些信息转换为相应的域模型,以便服务逻辑能够使用它。
而且,在我看来,这也适用于存储库:存储库将数据持久化到外部系统(例如,数据库,甚至是其他REST服务),并在请求时将其带回。为此,它可能需要将域模型转换为简化的DTO,以便能够在目标系统中持久化。
适配器的思想是,业务逻辑不需要知道如何转换要在REST/SOAP/MySQL/.协议。这是适配器的任务。因此:DTO应该留在适配器中,如果需要的话。
你真的需要DTO吗?
DTO是系统中数据的另一个抽象。你也应该考虑一下你是否真的需要它们。您可能会也可能不会,这取决于您想要对这些信息做什么。如果您使用自己编写查询的数据库持久化数据(这意味着您没有使用ORM映射程序),则可能根本不需要DTO,因为您可以直接从域模型中提取相关信息。
另一方面,如果您对对象使用反序列化器(比如Jackson用于JSON或诸如此类的东西),您可能会发现自己需要DTO,因为这些工具有时需要一些特殊的需求,以便能够将数据序列化并反序列化为对象。在这里,您可能需要一步来使用DTO,然后才能将其转换为域对象,反之亦然。
顺便问一下:这个问题也很好地回答了on softwareengineering.stackexchange.com。
https://stackoverflow.com/questions/61303236
复制相似问题