当前位置: 首页 > news >正文

别再被VO、BO、PO、DTO、DO绕晕!今天用一段代码把它们讲透

一、先放结论

它们都是“为了隔离变化”而诞生的马甲

缩写英文全称中文直译出现位置核心目的POPersistent Object持久化对象数据库 ↔ 代码一张表一行记录的直接映射DODomain Object领域对象核心业务逻辑层充血模型,封装业务行为BOBusiness Object业务对象应用/服务层聚合多个DO,面向用例编排DTOData Transfer Object数据传输对象进程/服务间精简字段,抗网络延迟VOView Object视图对象控制层 ↔ 前端展示友好,防敏感字段泄露
一句话总结: PO 管存储,DO 管业务,BO 管编排,DTO 管网络,VO 管界面。
下面上代码,咱们边喝奶茶边讲。

二、业务场景

用户下一单“芋泥波波奶茶”

需求:

用户选好规格(大杯、少冰、五分糖)。
点击“提交订单”,前端把数据发过来。
后端算价格、扣库存、落库,返回“订单创建成功”页面。

整条链路里,我们到底需要几个对象?

三、从数据库开始:PO

PO是Persistent Object的简写 PO 就是“一行数据一个对象”,字段名、类型和数据库保持一一对应,不改表就不改它。

kotlin 体验AI代码助手 代码解读复制代码// 表:t_order
@Data
@TableName("t_order")
public class OrderPO {
   private Long id;          // 主键
   private Long userId;      // 用户ID
   private Long productId;   // 商品ID
   private String sku;       // 规格JSON
   private BigDecimal price; // 原价
   private BigDecimal payAmount; // 实付
   private Integer status;   // 订单状态
   private LocalDateTime createTime;
   private LocalDateTime updateTime;
}

注意:PO 里绝不能出现业务方法,它只是一个“数据库搬运工”。

四、核心业务:DO

DO 是“有血有肉的对象”,它把业务规则写成方法,让代码自己说话。

csharp 体验AI代码助手 代码解读复制代码// 领域对象:订单
public class OrderDO {

   private Long id;
   private UserDO user;      // 聚合根
   private MilkTeaDO milkTea; // 商品
   private SpecDO spec;      // 规格
   private Money price;      // Money是值对象,防精度丢失
   private OrderStatus status;

   // 业务方法:计算最终价格
   public Money calcFinalPrice() {
       // 会员折扣
       Money discount = user.getVipDiscount();
       // 商品促销
       Money promotion = milkTea.getPromotion(spec);
       return price.minus(discount).minus(promotion);
  }

   // 业务方法:下单前置校验
   public void checkBeforeCreate() {
       if (!milkTea.hasStock(spec)) {
           throw new BizException("库存不足");
      }
  }
}

DO 可以引用别的 DO,形成聚合根。它不关心数据库,也不关心网络。

五、面向用例:BO

BO 是“场景大管家”,把多个 DO 攒成一个用例,常出现在 Service 层。

scss 体验AI代码助手 代码解读复制代码@Service
public class OrderBO {

   @Resource
   private OrderRepository orderRepository; // 操作PO
   @Resource
   private InventoryService inventoryService; // RPC或本地
   @Resource
   private PaymentService paymentService;

   // 用例:下单
   @Transactional
   public OrderDTO createOrder(CreateOrderDTO cmd) {

       // 1. 构建DO
       OrderDO order = OrderAssembler.toDO(cmd);

       // 2. 执行业务校验
       order.checkBeforeCreate();

       // 3. 聚合逻辑:扣库存、算价格
       inventoryService.lock(order.getSpec());
       Money payAmount = order.calcFinalPrice();

       // 4. 落库
       OrderPO po = OrderAssembler.toPO(order, payAmount);
       orderRepository.save(po);

       // 5. 返回给前端需要的数据
       return OrderAssembler.toDTO(po);
  }
}

BO 的核心是编排,它把 DO、外部服务、PO 串成一个完整的业务动作。

六、跨进程/服务:DTO

DTO 是“网络快递员”,字段被压缩成最少,只带对方需要的数据。

1)入口 DTO:前端 → 后端
kotlin 体验AI代码助手 代码解读复制代码@Data
public class CreateOrderDTO {
   @NotNull
   private Long userId;
   @NotNull
   private Long productId;
   @Valid
   private SpecDTO spec; // 规格
}

2)出口 DTO:后端 → 前端
kotlin 体验AI代码助手 代码解读复制代码@Data
public class OrderDTO {
   private Long orderId;
   private String productName;
   private BigDecimal payAmount;
   private String statusDesc;
   private LocalDateTime createTime;
}

DTO 的字段命名常带 UI 友好词汇(如 statusDesc),并且绝不暴露敏感字段(如 userId 在返回给前端时可直接省略)。

七、最后一步:VO

VO 是“前端专属快递”,字段可能二次加工,甚至带 HTML 片段。

typescript 体验AI代码助手 代码解读复制代码@Data
public class OrderVO {
   private String orderId; // 用字符串避免 JS long 精度丢失
   private String productImage; // 带 CDN 前缀
   private String priceText; // 已格式化为“¥18.00”
   private String statusTag; // 带颜色:green/red
}

VO 通常由前端同学自己写 TypeScript/Java 类,后端只负责给 DTO,再让前端 BFF 层转 VO。如果你用 Node 中间层或 Serverless,VO 就出现在那儿。

八、一张图记住流转过程
scss 体验AI代码助手 代码解读复制代码前端页面
  │ JSON
  ▼
CreateOrderVO (前端 TS)
  │ 序列化
  ▼
CreateOrderDTO (后端入口)
  │ BO.createOrder()
  ▼
OrderDO (充血领域模型)
  │ 聚合、计算
  ▼
OrderPO (落库)
  │ MyBatis
  ▼
数据库

返回时反向走一遍:
java 体验AI代码助手 代码解读复制代码数据库
  │ SELECT
OrderPO
  │ 转换
OrderDTO
  │ JSON
OrderVO (前端 TS 渲染)

九、常见疑问答疑

为什么 DO 和 PO 不合并? 数据库加索引、加字段不影响业务;业务改规则不改表结构。隔离变化。
DTO 和 VO 能合并吗? 小项目可以,但一上微服务或多端(App、小程序、管理后台),立马爆炸。比如后台需要用户手机号,App 不需要,合并后前端会拿到不该看的数据。
BO 和 Service 有什么区别? BO 更贴近用例,粒度更粗。Service 可能细分读写、缓存等。命名随意,关键看团队约定。

十、一句话背下来

数据库里叫 PO,业务里是 DO,编排靠 BO,网络走 DTO,前端看 VO。

http://www.jsqmd.com/news/42746/

相关文章:

  • 2025 最新推荐!装盒机厂家权威榜单发布,覆盖多行业专用设备及创新解决方案内外盒 / 面膜 / 电子产品 / 玩具 / 日用品装盒机厂家推荐
  • 2025 年试验仪厂家最新推荐榜:乳化沥青 / 沥青混合料 / 高低温等全品类检测设备权威品牌排行榜马歇尔稳定度/沥青动力黏度/高低温试验仪公司推荐
  • 2025少儿免费编程体验课怎么选?5大优质机构推荐,家长收藏
  • 2025年11月复合型塑胶跑道厂家最新推荐,透气型塑胶跑道/自结纹塑胶跑道/老国标塑胶跑道/全塑型塑胶跑道/综合表现突出厂家推荐
  • 2025 最新推荐折盒机制造厂家权威排行榜:半自动 / 全自动 / 定制型设备优选,国际测评认证实力品牌全解析
  • 2025 最新推荐!自动包装生产线厂家权威榜单:食品 / 日化 / 智能 / 柔性等多场景高效解决方案测评发布
  • 2025年11月国内旧房翻新公司权威排行:专业服务商综合实力大比拼
  • 2025年11月国内旧房翻新公司排名前十推荐榜单
  • 2025年国内旧房翻新公司口碑推荐排行榜前十强
  • 2025年国内旧房翻新公司排名Top5推荐榜单
  • LLaMA-Factory 使用 Qwen2-1.5B-Instruct 在华为 Ascend NPU docker环境上进行模型微调
  • 是搬运他人的,来源于xt2025
  • 2025 最新石灰料仓厂家推荐!专利加持 + 多场景适配石灰料仓及投加系统 / 装置优质厂家排行榜石灰料仓投加系统/石灰料仓投加装置公司推荐
  • 坯子插件 v3.2.5 for SketchUp 2022-2024下载地址与安装教程
  • 20232310 2025-2026-1 《网络与系统攻防技术》实验六实验报告
  • 2025年环形导轨输送线直销厂家权威推荐榜单:环形导轨/圆弧导轨/ 环形导轨生产线源头厂家精选
  • Bootstrap在MySQL数据管理中作用大吗
  • PlantAssistant-管道数据文件PCF
  • Homework - Section Three
  • 【HD200I A2(8T)】青翼凌云科技-基于昇腾 310B 的智能计算模组
  • 2025 年尼龙扎带厂家最新推荐排行榜:不锈钢扎带、线卡、定位片等配件源头厂家权威测评推荐尼龙扎带厂家推荐
  • STM32 缓上电导致死机的问题分析
  • 2025! jenkins 添加节点
  • wtl with visual studio 2022
  • 生成用于验证 TDM slot 配置的波形
  • 20251117noip模拟赛
  • Bootstrap在MySQL应用中有何优势
  • blob字段在oracle中如何进行索引
  • [Python刷题记录]-多数元素-技巧-简单
  • 2025年武汉喷码机厂家最新企业推荐榜,油墨喷码机/手持喷码机/日期喷码机/喷码机维修/聚焦服务品质与产品竞争力深度剖析