agg*_*ech 7 domain-driven-design dto
从我所阅读和实现的内容来看,DTO是从Data模型中保存值子集的对象,在大多数情况下,它们是不可变对象.
我需要传递新值还是更改回数据库的情况怎么样?
我应该直接使用我的表达层中的DAL中的数据模型/实际实体吗?
或者我应该创建一个可以从表示层传递到业务层的DTO,然后将其转换为实体,然后通过ORM调用在DB中进行更新.这写的代码太多了吗?我假设如果表示层没有数据模型的概念,则需要这样做.如果我们采用这种方法,我应该在提交更改之前在BLL层再次获取对象吗?
gui*_*e31 20
一些想法:
DTO是一个加载术语,但由于它代表数据传输对象,我将其视为一个纯技术的,可能可序列化的容器,可以将数据从一个点传递到另一个点,通常是跨层或可能是层.在处理业务问题的层中,例如DDD中的Domain层,这些流通的小数据结构往往被命名为Value Objects,因为它们具有商业意义并且是域的泛在语言的一部分.DTO和Value Objects之间存在各种细微差别,例如您通常不需要比较DTO,而比较和相等是VO中的一个重要问题(如果它们的封装数据相等,则两个VO是相等的).
DDD强调丰富域模型的思想.这意味着您通常不会简单地将DTO的一对一映射到域实体,而是尝试将业务操作建模为实体中的意图揭示方法.例如,你不会用setter方法来修改User
的Street
,City
并且ZipCode
而是调用一个moveTo(Address newAddress)
方法来代替,Address
是在域层声明的值对象.
DTO通常不会到达Domain层,而是通过Application层的过滤器.它可以是控制器或专用的应用程序服务.它的应用层对象知道如何将从客户端获得的DTO转换为对域层实体(通常是从存储库加载的聚合根)的正确调用.上面的另一个改进是构建基于任务的UI,其中用户不发送以数据为中心的DTO,而是发送反映其最终目标的命令.
因此,将DTO映射到实体并不是DDD的实际操作方式,它更多地表示面向CRUD的方法.
我应该直接使用表示层中 DAL 中的数据模型/实际实体吗?
这对于中小型项目来说是可以的。但是,当您的大型项目有超过 5 名开发人员,其中不同的层分配给不同的团队时,那么使用 DTO 将数据层与表示层分开,该项目就会受益。
中间有 DTO,表示层的任何更改都不会影响数据层(反之亦然)
或者我应该创建一个可以从表示层传递到业务层的 DTO,然后将其转换为实体,然后通过 ORM 调用在数据库中进行更新。这样写代码是不是太多了?我假设如果表示层没有数据模型的概念,那么这是需要的。如果我们采用这种方法,我是否应该在提交更改之前在 BLL 层再次获取对象?
对于创建新实体,这是通常的方法(例如“新用户”)。为了更新现有实体,您不需要将 DTO 转换为实体,而是获取现有实体,映射新值,然后启动 ORM 更新。
UpdateUser(UserDto userDto)
{
// Fetch
User user = userRepository.GetById(userDto.ID);
// Map
user.FirstName = userDTO.FirstName;
user.LastName = userDTO.LastName;
// ORM Update
userRepository.Update(user);
userRepository.Commit();
}
Run Code Online (Sandbox Code Playgroud)
对于拥有许多开发人员的大型项目来说,编写过多代码的缺点与其提供的解耦的巨大优势相比是微乎其微的。
请参阅我关于为什么使用 DTO 的文章