实体类应高内聚低耦合:只承载领域数据,不包含业务逻辑、操作行为或外部依赖;需配合分层架构,通过dto转换隔离各层。

实体类本身不承担业务逻辑,它的核心任务是准确、安全地承载领域数据。设计得当的实体类,是高内聚低耦合架构的起点,而不是终点。
实体类要高内聚:只管“自己是谁”,不管“别人怎么用”
高内聚对实体类来说,意味着它内部所有成员都服务于同一个目的——定义一个清晰、自洽的业务概念。比如 User 类,它的字段(id、name、email、status)和对应的方法(getter/setter、isActivated())必须全部围绕“用户身份与状态”这个单一职责展开。
- 不放业务校验逻辑:不要在
setEmail(String email)里写邮箱格式校验或唯一性检查——那是 UserValidator 的事; - 不掺操作行为:不要加
sendWelcomeEmail()或generateReport()这类方法——它们变化原因不同,会拉低内聚; - 不暴露实现细节:避免 public 字段、避免直接返回可变集合(如
public List<order> getOrders()</order>应改为public List<order> getOrdersCopy()</order>或封装为不可变视图)。
实体类要低耦合:不依赖外部,也不被外部强绑定
低耦合体现在实体类尽量“无感”于框架、数据库、序列化工具等外部环境。它应是一个纯粹的 POJO(Plain Old Java Object),不引入 Spring、MyBatis、Jackson 等任何第三方注解或接口。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不用
@Data(Lombok)盲目生成所有方法:它可能意外暴露toString()或hashCode()引发循环引用问题;建议按需使用@Getter/@Setter,并手动控制关键方法; - 避免在实体中 new 其他服务或调用静态工具类:比如
new ObjectMapper().writeValueAsString(this)是典型耦合;序列化应交给 DTO 层或 Controller 层统一处理; - 数据库主键、时间戳等技术字段(如
create_time)不硬编码为 Java 字段名:用@Column(name = "create_time")显式映射,保持实体语义纯净。
配合分层结构,让实体真正“居中而立”
实体类不是孤岛,它的价值在分层协作中体现。正确用法是:
- DAO 层用 Entity:仅用于 JPA/Hibernate 的持久化映射,字段与表结构严格对应;
-
Service 层用 DTO 或 VO:接收请求用
OrderCreateRequest,返回结果用OrderSummaryVO,实体类不直接暴露给上层; - 跨层传递靠转换:用 MapStruct 或手动构造器完成 Entity ↔ DTO 转换,切断各层对彼此内部结构的依赖。
一个干净的 User 实体示例
(无 Lombok,无业务逻辑,无框架侵入)
public class User {
private Long id;
private String name;
private String email;
private UserStatus status;
private LocalDateTime createdAt;
// 无参构造器(JPA 必需)
public User() {}
// 推荐:提供带关键字段的构造器,便于测试和构建
public User(String name, String email) {
this.name = name;
this.email = email;
this.status = UserStatus.ACTIVE;
this.createdAt = LocalDateTime.now();
}
// 仅暴露必要访问器
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public UserStatus getStatus() { return status; }
// 状态变更应由 Service 控制,这里不提供 setStatus —— 封装行为边界
public boolean isActive() {
return UserStatus.ACTIVE == this.status;
}
}Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










