一、什么是DTO和VO
Data Transfer Object (DTO) 和 Value Object (VO) 是在软件开发中非常常见的两种数据结构,但是它们的用途和含义有所不同。
DTO 在不同层次的应用程序之间传输数据,并且DTO负责封装与业务相关的数据和传输规则,而且它们是完全分离的层次结构。DTO 对象通常是无状态,这意味着当数据传输完成后就可以将 dto 对象舍弃,可以用于 RPC(Remote Procedure Call) 等情境。
VO 不是用于数据传输的,而是用于在前端与用户交互,展示业务相关的数据。将一个领域模型的状态“塞”到vo中,以传递给前端ui层。
二、DTO and VO示例
1. DTO示例
public class UserDTO {
    private Long id;
    private String name;
    private Integer age;
    // getter and setter ...
}
DTO对象设计简单明了,注意到的是,我们定义了一个公开的无参数的构造器,这是因为我们将要使用反序列化技术将相关数据解析成与此对象相对应的实例。
2. VO示例
public class UserVO {
    private String name;
    private Integer age;    
    // getter and setter ...
}
请留意到这里 VO 与 DTO 之间的显著差异。首先,我们没有定义 ID,它不是为了向业务层返回而存在的。其次是 public 无参数构造器,也是为了前端界面进行数据组装时所必须的。显然,我们不需要复制字段,更不需要加额外的方法,因为 VO 并不承担任何业务逻辑。
三、DTO and VO在实战开发中的应用
1. 应用场景
在应用程序中,DTO 和 VO 应该扮演着不同的角色。DTO 可以用于跨网络传输数据,可以克服不同操作系统和语言之间的差异。数据在网络传输时,可能会发生丢失。DTO 可以在应用程序的不同层之间传递数据,减少数据层次结构。
VO 在前端展示中扮演着非常重要的角色。UI 设计师可以使用 VO 减少 HTML 模板中的逻辑。VO 还有助于确保在请求超过一次时整个数据的一致性。
2. 实战应用举例
假设我们有一个用户管理系统,并且我们需要展示用户列表到UI层。假设有两个前端页面需要用户列表数据:用户管理界面和用户详情页面。
这个时候,我们可以实现两个DTO对象:UserListDTO用于传递完整的用户列表信息和 UserDetailsDTO 用于传递单个用户的详细信息。
//UserListDTO
public class UserListDTO{
    private Long userId;
    private String userName;
    private Integer userAge;   
    // getter and setter ...
}
//UserDetailsDTO
public class UserDetailsDTO{
    private String userName;
    private Integer userAge;
    private String userAddress;
    private Integer userRole;
    // getter and setter ...
}
//UserMapper.java
public UserListDTO mapToUserListDTO(UserEntity entity){
    UserListDTO dto = new UserListDTO();
    dto.setUserId(entity.getId());
    dto.setUserName(entity.getName());
    dto.setUserAge(entity.getAge());
    return dto;
}
//UserController.java
@GetMapping("/all")
public UserListDTO getAllUsers(){
    List users = userService.getAllUsers();
    return users.stream()
                .map(user->userMapper.mapToUserListDTO(user))
                .collect(Collectors.toList());
}
//UserController.java
@GetMapping("/{id}")
public UserDetailsDTO getUserDetails(@PathVariable Long id){
    UserEntity user = userService.getUserById(id);
    return userMapper.mapToUserDetailsDTO(user);
}
这个时候,前端页面也相应发生了变化,显示用户列表和单个用户详情信息。前端接收到的数据格式也与DTO中定义的完全一致。
四、结论
DTO和VO不应该仅仅只是一个由getter和setter方法组成的带注释 Java Bean,它们应该是有目的的数据结构,每个字段都需要在DTO或VO上进行明确的分类和注释。DTO 和 VO 广泛应用于各级别的应用程序,使数据传输变得更加高效,更容易管理,无论是对于后端还是前端来说。
原创文章,作者:EMAZL,如若转载,请注明出处:https://www.506064.com/n/334821.html
微信扫一扫 
支付宝扫一扫