使用DDD做参数检验
关于在实体类中进行参数校验的"优雅"方式,有一个叫做"领域驱动设计"(Domain-Driven Design,简称DDD)的方法,它推崇"丰富的模型"(Rich Model)。这种方法强调的是将业务规则和逻辑封装到实体或值对象中,使得它们不仅仅是数据的容器,而是拥有行为的完整模型。
基于这个思路,我们可以在实体类中定义相关的业务方法和校验方法:
1. **定义实体类,并在其中封装校验方法**
public class User {
private String username;
private int age;
// ... 其他字段和getter/setter
// 构造函数中进行校验
public User(String username, int age) {
setUsername(username);
setAge(age);
}
public void setUsername(String username) {
if (username == null || username.isEmpty()) {
throw new IllegalArgumentException("用户名不能为空");
}
this.username = username;
}
public void setAge(int age) {
if (age <= 0) {
throw new IllegalArgumentException("年龄必须大于0");
}
this.age = age;
}
// 可以添加其他与User相关的业务方法
public void updateProfile(String newUsername, int newAge) {
setUsername(newUsername);
setAge(newAge);
}
}
- 在服务层调用实体类的相关方法:
这里,由于实体类的构造方法或者setter方法会进行参数校验,所以服务层的逻辑将变得非常简单和清晰。
@Service
public class UserService {
public void createUser(String username, int age) {
User user = new User(username, age);
// ... 保存用户或其他业务逻辑
}
public void updateUserProfile(User user, String newUsername, int newAge) {
user.updateProfile(newUsername, newAge);
// ... 更新用户或其他业务逻辑
}
}
- 在Controller层捕获并处理异常:
Controller层的处理方式与前面相同,捕获异常并转换为合适的HTTP响应。
这种方式的好处是将数据和与数据相关的行为都封装在一起,形成一个真正意义上的"对象"。不仅可以用于参数校验,还可以封装更多的业务逻辑。当然,这也要求我们在设计实体类时更加小心,确保内部的状态始终保持一致和有效。
发表评论