虽然我不能说为什么团队会做出这个决定,但我绝对同意 DTO/VM 的概念不是很清楚。
我认为,基本思想类似于 MVP/MVC 模式,其中经常引入新的视图模型来获得 MVVM 模式。因此,不影响任何视图的 DTO 被“推送”到实际的模型/控制器层中。没关系,如果您说 DTO 是服务之间的传输对象。
但是,我们也遇到了“麻烦”,并与旧 jhipster-app 中的层和 DTO、VM 等进行了大量讨论。我们是在 jhipster 引入 DTO 和 Mapstruct 的同时开始的。在我们使用 Jhipster 的新项目中,我们总是删除所有 DTO 和 VM。首先:(托管)UserVM/DTO 的东西,这非常令人困惑。这有几个原因:
我们的应用程序的服务器端从来没有虚拟机。在视图完全基于 javascript/angular 的 jhipster 应用程序中,视图模型必须存在。我们经常有其他使用 REST-API 的应用程序,这些应用程序不是视图。因此,尤其是在微服务架构中,我永远不会在 REST-API“视图”甚至“视图模型”中调用某些东西。
因此,在没有用 Java 编写视图(使用 JSP 左右)的此类应用程序中,您永远不会在我们的 Java 代码中找到术语“VM”。此外,可能有不同类型的视图(例如 Angular Web 应用程序、iOS 应用程序、桌面客户端或其他东西),它们中的每一个都有其他视图、视图部件、小部件,因此需要其他视图模型。最后,有人说 REST-API 可能不会提供任何不是真正资源/实体的东西......
所以,您说 jhipster 中的虚拟机实际上是 DTO 是绝对正确的。但是,正如您也所说,“DTO”存在问题,因为通常 DTO 只是一个无状态传输对象,用于封装两个或多个服务(或系统)之间的公共值,没有任何逻辑。我们认为这也是自上而下(REST)API 驱动和自下而上领域驱动设计之间的架构问题,它们以某种方式混合在 JHipster 应用程序中。与您的观点类似,我认为 JHipster 在它应该是域对象(或实体)的地方使用 DTO。例如。托管用户不是 VM 或 DTO,它是一个实体。我认为,这里的问题是,有些人认为只有基于 JPA 的实体才是领域对象,不可能有其他领域对象(实体)。
最后,我们决定引入一种称为 ADO(API 数据对象或访问数据对象)的新类型,因为我们没有找到合适的术语。 ADO 被比作 jhipster 一个 VM、一个 DTO 甚至一个没有任何逻辑的实体。一个普通的“API 层”只读写 ADO。该层用于 REST API 控制器以及可供插件使用的 Java API。这使我们能够在不添加任何特定内部实体或域对象的情况下使用 client-API-jar 发送所有 ADO。由于 REST-API 和每个插件使用相同的 ADO(因此具有相同的描述和结构),因此开发人员不会感到困惑,并且面向资源的外部层与使用另一种业务逻辑的内部层适当分离,而不仅仅是资源-基于。
作为内部层一部分的其他所有内容,例如实体、派生实体、实体的子集或超集,大部分都是域对象。因此,我们从这个内部层、业务逻辑等中删除了所有 VM 和 DTO。
总而言之:为了从外部访问封装内部 (JPA) 实体,我们使用 ADO,因为除了视图之外可能还有其他实体。这些 ADO 就 jhipster VM 和 DTO 而言。但是在公共 API 层的内部,我们从不使用任何 DTO 或 VM 甚至 ADO,因为这些实体大多是域对象。