代码架构之 BO、PO、DTO

BO、PO、DTO

用于数据封装和传输的常见对象类型

BO(Business Object,业务对象)

用于封装业务逻辑和业务规则的对象,通常包含与业务相关的属性和方法,是业务层的核心对象。

例如:处理订单计算、用户权限验证等业务逻辑的对象。

PO(Persistent Object,持久化对象)

与数据库表结构一一对应,用于实现数据的持久化(存储到数据库或从数据库读取)。

例如:对应数据库中 "用户表" 的 UserPO 类,属性与表字段完全匹配。

DTO(Data Transfer Object,数据传输对象)

专门用于不同层(如前端与后端、服务间)的数据传输,可根据传输需求裁剪或组合数据,减少冗余传输。

三者的核心区别

在于用途:PO 聚焦数据存储,DTO 聚焦数据传输,BO 聚焦业务逻辑处理。

协作流程

前端请求 → 服务层接收 req DTO → BO 处理业务(操作 PO) → 转换为 resp DTO → 返回给前端

让数据职责清晰,便于维护和扩展

示例

UserBO

java 复制代码
// BO(Business Object):封装业务逻辑,协调PO和其他资源
public class UserBO {
    // 依赖持久层接口(实际开发中通过注入方式获取)
    private UserMapper userMapper;
    // 依赖工具类(如密码加密、日期格式化)
    private PasswordEncoder passwordEncoder;
    private DateTimeFormatter dateTimeFormatter;

    // 业务方法1:创建用户(包含密码加密、默认状态设置等业务逻辑)
    public UserPO createUser(String username, String rawPassword) {
        // 1. 密码加密(业务规则:密码必须加密存储)
        String encryptedPassword = passwordEncoder.encode(rawPassword);
        
        // 2. 设置默认值(业务规则:新用户默认状态为"正常")
        UserPO userPO = new UserPO();
        userPO.setUsername(username);
        userPO.setPassword(encryptedPassword);
        userPO.setCreateTime(LocalDateTime.now());
        userPO.setStatus(1); // 1表示正常
        
        // 3. 持久化到数据库
        userMapper.insert(userPO);
        return userPO;
    }

    // 业务方法2:将PO转换为DTO(包含数据格式化、字段映射等逻辑)
    public UserDTO convertToDTO(UserPO userPO) {
        UserDTO dto = new UserDTO();
        dto.setId(userPO.getId());
        dto.setUsername(userPO.getUsername());
        
        // 业务规则:昵称默认等于用户名(可扩展为从其他表获取)
        dto.setNickname(userPO.getUsername());
        
        // 业务规则:日期格式化(数据库存储LocalDateTime,前端展示字符串)
        dto.setCreateTimeStr(dateTimeFormatter.format(userPO.getCreateTime()));
        
        // 业务规则:状态码转描述(1→正常,0→禁用)
        dto.setStatusDesc(userPO.getStatus() == 1 ? "正常" : "禁用");
        
        return dto;
    }

    // 其他业务方法:如用户状态变更、权限校验等
    public void updateStatus(Long userId, Integer newStatus) {
        // 业务规则:校验状态合法性
        if (newStatus != 0 && newStatus != 1) {
            throw new IllegalArgumentException("无效的状态值");
        }
        userMapper.updateStatus(userId, newStatus);
    }
}

UserDTO

java 复制代码
// DTO(Data Transfer Object):用于前端与后端之间的数据传输
// 只包含前端需要展示或提交的字段,避免传输敏感信息(如密码)
public class UserDTO {
    private Long id;             // 用户ID(前端展示用)
    private String username;     // 用户名(前端展示/提交用)
    private String nickname;     // 昵称(前端展示用,可能由业务层计算生成)
    private String createTimeStr; // 格式化后的创建时间(前端展示用,如"2023-10-01 12:00:00")
    private String statusDesc;   // 状态描述(前端展示用,如"正常"、"禁用")

    //  getter和setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getNickname() { return nickname; }
    public void setNickname(String nickname) { this.nickname = nickname; }
    public String getCreateTimeStr() { return createTimeStr; }
    public void setCreateTimeStr(String createTimeStr) { this.createTimeStr = createTimeStr; }
    public String getStatusDesc() { return statusDesc; }
    public void setStatusDesc(String statusDesc) { this.statusDesc = statusDesc; }
}

UserPO

java 复制代码
// PO(Persistent Object):与数据库表结构一一对应
// 假设数据库有一张 user 表,字段包括 id、username、password、create_time、status
public class UserPO {
    private Long id;             // 对应数据库id字段
    private String username;     // 对应数据库username字段
    private String password;     // 对应数据库password字段(存储加密后的密码)
    private LocalDateTime createTime;  // 对应数据库create_time字段
    private Integer status;      // 对应数据库status字段(1-正常,0-禁用)

    //  getter和setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public LocalDateTime getCreateTime() { return createTime; }
    public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
    public Integer getStatus() { return status; }
    public void setStatus(Integer status) { this.status = status; }
}

UserService

java 复制代码
// 服务层示例:展示BO、PO、DTO的协作流程
@Service
public class UserService {
    @Autowired
    private UserBO userBO;  // 注入业务对象
    @Autowired
    private UserMapper userMapper;  // 注入持久层接口

    // 示例:查询用户并返回给前端
    public UserDTO getUserById(Long userId) {
        // 1. 从数据库查询PO
        UserPO userPO = userMapper.selectById(userId);
        if (userPO == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 2. 通过BO将PO转换为DTO(包含业务逻辑)
        return userBO.convertToDTO(userPO);
    }

    // 示例:创建用户
    public UserDTO createUser(String username, String password) {
        // 1. 通过BO处理业务逻辑并保存PO
        UserPO userPO = userBO.createUser(username, password);
        
        // 2. 转换为DTO返回
        return userBO.convertToDTO(userPO);
    }
}