嗨,我正在开发一个应用程序,需要使用Hibernate处理复杂的域模型。这个应用程序使用Spring MVC,并且在表示层中使用域对象非常混乱,所以我认为我应该使用往返于服务层的DTO,以便这些对象与我在视图中所需的内容相匹配。现在假设我有一个CarLease实体,它的属性不是简单的java原语,而是由Make、Model等其他实体组成
public class CarLease {
private Make make;
Private Model model;
.
.
.
}
大多数属性都采用这种方式,并且可以使用jsp视图上的下拉选择来选择它们,每个属性都会向控制器回发一个ID。
现在考虑一些标准用例:创建、编辑、显示
您将如何对表示DTO建模,以用作表单支持对象以及表示层和服务层之间的通信?
您会为每个案例创建不同的DTO (创建、编辑、显示),您会为复杂属性创建DTO吗?如果是这样,您会在哪里将ID转换为entity?
您将如何以及在何处处理验证、DTO/域组装,您将从服务层方法中返回什么?(创建、编辑、获取)
正如您所看到的,现在我将受益于将我的视图从域对象(非常复杂,有许多我不需要的东西)中分离出来。但我很难找到任何现实世界的例子和最佳实践。我需要一些从上到下的架构指导,请记住,我将使用Spring MVC,以防在您的应用程序上发挥作用。
提前谢谢。
发布于 2010-04-11 21:56:50
无论如何(我是在C# .net中开发的--但这些原则希望对您仍然有帮助),我定义了一组类型(DTO),用于在业务层和数据层之间交换数据;并且每个域对象/实体都有多个类型。这些类被定义为简单的类。
其中每一个都是考虑到特定的任务而构建的,例如:
每种类型都被设计为只保存与给定任务相关的信息。例如,"big“将返回上次修改的日期,但我不希望在我的保存和更新类型中出现这种情况,因为我在数据访问层中填充了这些类型。
此外,对于我的应用程序,这些类型存在于一个公共程序集中-因此它们可以在任何层之间重用,而不仅仅是在业务层和数据层之间。
架构Fit
这种方法没有什么特别之处,它有自己的优点和缺点;这些优点和缺点到底是什么以及它们如何影响您将取决于很多东西-我猜您的里程会有所不同-但它肯定已经为我服务了很多年。
人们经常对“关注点分离”大惊小怪-这是一个非常明智的举动;这与DTO有关,因为它们是在层(和服务、组件等)之间交换的,所以在究竟应该在哪里划线时总是有一些模棱两可的地方。
我采用的方法是,如果一些信息适合在to层之间交换,那么它可能适合在任何数量的层之间交换-所以为什么不让所有人都可以访问它呢?如果您只是传递信息,它还可以省去重新转换信息的麻烦。
就复杂性而言,有两种方法来处理:
是否要为主实体的复杂属性创建?
我发现自己做DTO有以下两个原因之一:
我知道我需要公开(推送)一些数据,
因为它们都是在一个公共的程序集中定义的,没有一个组件“拥有”它,这有助于迫使你从“域”的角度来思考,而不是从以组件为中心的角度来考虑;在某种程度上,这将影响DTO的设计(平衡重用与SRP)。
在这两种情况下,DTO可以是特定于特定需求的,也可以是通用的;例如,只有一个int和一个字符串的DTO并不少见,它是用来发送到dropdownlists的那种东西。
我发回的大多数DTO集合(从DAL到BL)都是特定于某个概念的,而不是通用的。我通过我提供的构造函数强制执行这些非常基本的规则:每个参数都是必需的。我不确定这是否回答了你的问题“你是如何管理组装和验证的”。
发布于 2010-04-11 22:20:10
服务层应该返回DTO而不是EJB对象的想法主要是在EJB3/JPA时代之前的想法。在CRUD过程中,您可以从使用模型对象(也称为实体)。
但是,在用于性能优化时,您可以从使用DTO中获益,例如,当模型对象太大时,或者当您使用某些智能连接聚合模型数据时。
因此,除非您是在SOA下进行工程设计,否则我不建议使用DTO进行CRUD操作。
发布于 2010-04-12 02:27:36
您是否考虑过命令查询职责分离(CQRS)原则?简而言之,它是一种架构原则,提倡使用单独的组件进行读取和修改操作。
修改是使用发送给域模型的命令完成的。您的NewCarLeaseDTO看起来像一个命令-- CreateNewCarLeaseCommand。它们包含特定操作所需的所有数据。
另一方面,读取(无论是列表vies还是详细vies)直接在底层数据存储(SQL数据库)上完成。这里有许多可能性,从使用相同的数据存储来支持读取和写入部分,到通过发布/订阅基础设施连接两个独立的数据存储。
当使用后一种(两个存储)方法来读取端时,许多(比如Udi Dahan)提倡使用所谓的持久化视图。这意味着将数据直接存储在视图可使用的表单中。转换(反规范化)是在模型更新后进行同步时完成的。
如果你想了解更多关于CQRS的知识,我推荐阅读Udi Dahan和Greg Young。
https://stackoverflow.com/questions/2618617
复制相似问题