PO (Persistent Object)
- 全称:Persistent Object(持久化对象)。
- 用途:用于与数据库表直接映射的对象。
- 特点:
- 通常与数据库表一一对应。
- 包含与数据库字段对应的属性和方法。
- 用于 ORM(对象关系映射)框架(如 MyBatis、Hibernate)操作数据库。
public class UserPO {
private Long id;
private String username;
private String password;
private Date createTime;
// Getter 和 Setter 方法
}
DTO (Data Transfer Object)
- 全称:Data Transfer Object(数据传输对象)。
- 用途:用于在不同层(如 Controller 层和 Service 层)之间传输数据。
- 特点:
- 通常不包含业务逻辑。
- 用于封装多个字段,减少网络传输次数。
- 可以根据需要组合或拆分数据
public class UserDTO {
private Long id;
private String username;
private String email;
// Getter 和 Setter 方法
}
1. VO 的定义
- 全称:Value Object(值对象)。
- 用途:用于封装一组相关的数据,通常表示某个特定的值或概念。
- 特点:
- 不可变性:VO 对象一旦创建,其属性值不可更改。
- 值相等性:两个 VO 对象如果属性值相同,则认为它们是相等的。
- 无行为:VO 通常不包含业务逻辑,仅用于存储数据。
2. VO 的使用场景
- 表示某个具体的值:例如,货币金额、日期范围、坐标点等。
- 封装复杂的数据结构:例如,地址信息、颜色值等。
- 用于领域驱动设计(DDD):在 DDD 中,VO 用于表示领域模型中的值对象。
3. VO 的示例
(1)简单的 VO
java
复制
public class Money { private final BigDecimal amount; private final String currency; public Money(BigDecimal amount, String currency) { this.amount = amount; this.currency = currency; } public BigDecimal getAmount() { return amount; } public String getCurrency() { return currency; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Money money = (Money) o; return Objects.equals(amount, money.amount) && Objects.equals(currency, money.currency); } @Override public int hashCode() { return Objects.hash(amount, currency); } }
(2)复杂的 VO
java
复制
public class Address { private final String street; private final String city; private final String postalCode; private final String country; public Address(String street, String city, String postalCode, String country) { this.street = street; this.city = city; this.postalCode = postalCode; this.country = country; } // Getter 方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Address address = (Address) o; return Objects.equals(street, address.street) && Objects.equals(city, address.city) && Objects.equals(postalCode, address.postalCode) && Objects.equals(country, address.country); } @Override public int hashCode() { return Objects.hash(street, city, postalCode, country); } }
4. VO 与其他对象类型的区别
类型 | 全称 | 用途 | 特点 | 示例场景 |
---|---|---|---|---|
PO | Persistent Object | 与数据库表直接映射的对象 | 与数据库字段一一对应,用于 ORM 操作 | MyBatis、Hibernate 中的实体类 |
DTO | Data Transfer Object | 在不同层之间传输数据 | 不包含业务逻辑,用于封装数据 | Controller 层与 Service 层之间的数据传输 |
VO | Value Object | 封装一组相关的数据,表示某个值 | 不可变,值相等性,无行为 | 货币金额、地址信息、坐标点等 |
5. VO 的优点
- 不可变性:确保数据的安全性,避免被意外修改。
- 值相等性:简化对象的比较逻辑。
- 语义清晰:通过 VO 可以更清晰地表达业务概念。
6. 实际应用示例
(1)表示货币金额
java
复制
public class Money { private final BigDecimal amount; private final String currency; public Money(BigDecimal amount, String currency) { this.amount = amount; this.currency = currency; } public BigDecimal getAmount() { return amount; } public String getCurrency() { return currency; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Money money = (Money) o; return Objects.equals(amount, money.amount) && Objects.equals(currency, money.currency); } @Override public int hashCode() { return Objects.hash(amount, currency); } }
(2)表示日期范围
java
复制
public class DateRange { private final LocalDate startDate; private final LocalDate endDate; public DateRange(LocalDate startDate, LocalDate endDate) { this.startDate = startDate; this.endDate = endDate; } public LocalDate getStartDate() { return startDate; } public LocalDate getEndDate() { return endDate; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DateRange dateRange = (DateRange) o; return Objects.equals(startDate, dateRange.startDate) && Objects.equals(endDate, dateRange.endDate); } @Override public int hashCode() { return Objects.hash(startDate, endDate); } }
- VO 是一种用于封装数据的对象类型,具有不可变性和值相等性。
- 它通常用于表示某个具体的值或概念(如货币金额、地址信息等)。
- 与
PO
和DTO
不同,VO
更注重数据的封装和语义表达。
在实际开发中,合理使用 VO
可以提高代码的可读性和可维护性,特别是在领域驱动设计(DDD)中,VO
是表示领域模型的重要组成部分。
2. VO 的使用场景
- 表示某个具体的值:例如,货币金额、日期范围、坐标点等。
- 封装复杂的数据结构:例如,地址信息、颜色值等。
- 用于领域驱动设计(DDD):在 DDD 中,VO 用于表示领域模型中的值对象。
4. VO 与其他对象类型的区别
类型 | 全称 | 用途 | 特点 | 示例场景 |
---|---|---|---|---|
PO | Persistent Object | 与数据库表直接映射的对象 | 与数据库字段一一对应,用于 ORM 操作 | MyBatis、Hibernate 中的实体类 |
DTO | Data Transfer Object | 在不同层之间传输数据 | 不包含业务逻辑,用于封装数据 | Controller 层与 Service 层之间的数据传输 |
VO | Value Object | 封装一组相关的数据,表示某个值 | 不可变,值相等性,无行为 | 货币金额、地址信息、坐标点等 |
5. VO 的优点
- 不可变性:确保数据的安全性,避免被意外修改。
- 值相等性:简化对象的比较逻辑。
- 语义清晰:通过 VO 可以更清晰地表达业务概念。
6. 实际应用示例
(1)表示货币金额
java
复制
public class Money { private final BigDecimal amount; private final String currency; public Money(BigDecimal amount, String currency) { this.amount = amount; this.currency = currency; } public BigDecimal getAmount() { return amount; } public String getCurrency() { return currency; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Money money = (Money) o; return Objects.equals(amount, money.amount) && Objects.equals(currency, money.currency); } @Override public int hashCode() { return Objects.hash(amount, currency); } }
(2)表示日期范围
java
复制
public class DateRange { private final LocalDate startDate; private final LocalDate endDate; public DateRange(LocalDate startDate, LocalDate endDate) { this.startDate = startDate; this.endDate = endDate; } public LocalDate getStartDate() { return startDate; } public LocalDate getEndDate() { return endDate; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DateRange dateRange = (DateRange) o; return Objects.equals(startDate, dateRange.startDate) && Objects.equals(endDate, dateRange.endDate); } @Override public int hashCode() { return Objects.hash(startDate, endDate); } }
7. 总结
- VO 是一种用于封装数据的对象类型,具有不可变性和值相等性。
- 它通常用于表示某个具体的值或概念(如货币金额、地址信息等)。
- 与
PO
和DTO
不同,VO
更注重数据的封装和语义表达。
在实际开发中,合理使用 VO
可以提高代码的可读性和可维护性,特别是在领域驱动设计(DDD)中,VO
是表示领域模型的重要组成部分。
4. VO 与其他对象类型的区别
类型 | 全称 | 用途 | 特点 | 示例场景 |
---|---|---|---|---|
PO | Persistent Object | 与数据库表直接映射的对象 | 与数据库字段一一对应,用于 ORM 操作 | MyBatis、Hibernate 中的实体类 |
DTO | Data Transfer Object | 在不同层之间传输数据 | 不包含业务逻辑,用于封装数据 | Controller 层与 Service 层之间的数据传输 |
VO | Value Object | 封装一组相关的数据,表示某个值 | 不可变,值相等性,无行为 | 货币金额、地址信息、坐标点等 |