什么是基于贫血模型的传统开发模式?
贫血模型(Anemic Domain Model)是软件开发中的一种设计模式,通常与领域驱动设计(DDD)中的“丰富领域模型”(Rich Domain Model)相对。贫血模型指的是将业务逻辑与数据对象分离,把数据对象设计成仅包含数据(通常是属性字段),而不包含太多业务逻辑。也就是说,贫血模型通常没有多少行为,只有“数据容器”角色,这使得它在一些情况下显得过于简单,缺乏足够的表达能力。
贫血模型的特点:
仅包含数据字段:贫血模型的实体类通常只包含与数据库表映射的属性字段。
缺乏行为:业务逻辑通常不放在模型对象中,而是放在服务层或控制器中。模型本身只是数据的载体。
便于数据传输:由于模型对象本身只是数据字段,因此适合用于快速的数据传输、序列化或存储。
贫血模型的缺点:
业务逻辑分散:由于业务逻辑不在领域模型中,这就导致了业务逻辑会散布在服务层或其他地方,增加了系统的复杂性。
难以维护和扩展:当业务逻辑分散在不同的层次中时,增加或修改业务规则时往往需要在多个地方进行修改,容易引入错误。
代码不符合面向对象原则:面向对象设计提倡将数据和行为封装在一起,而贫血模型将数据和行为分离,违背了这一原则。
// 贫血模型中的实体类,只有数据字段,没有业务逻辑
public class User {
private String name;
private int age;
private String email;
// 构造函数
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// Getter 和 Setter 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
// 服务层的业务逻辑,业务逻辑与实体类分离
public class UserService {
// 注册用户的业务逻辑
public void registerUser(User user) {
// 这里可以进行一些简单的业务操作,但不会放在 User 类中
if (user.getAge() < 18) {
throw new IllegalArgumentException("User must be at least 18 years old");
}
// 其他注册逻辑,如保存到数据库等
System.out.println("User " + user.getName() + " registered successfully!");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建 User 对象
User user = new User("John Doe", 25, "john.doe@example.com");
// 调用服务层进行用户注册
UserService userService = new UserService();
userService.registerUser(user);
}
}
User 类(贫血模型):该类是一个典型的贫血模型实体类,只有数据字段(name、age、email)和简单的 getter/setter 方法。没有任何复杂的业务逻辑或行为。
UserService 类:业务逻辑(如用户注册)被放置在 UserService 服务层中,而不是 User 实体类中。在 UserService 中,我们编写了注册用户的逻辑,检查用户是否满足最小年龄要求,之后才执行注册操作。
客户端代码:在客户端代码中,我们创建了一个 User 对象,并通过 UserService 来处理相关的业务逻辑。这样,User 类只是一个简单的对象,完全没有包含任何复杂的逻辑。
什么是基于充血模型的 DDD 开发模式?
在贫血模型中,数据和业务逻辑被分割到不同的类中。充血模型(Rich Domain Model)正好相反,数据和对应的业务逻辑被封装到同一个类中。因此,这种充血模型满足面向对象的封装特性,是典型的面向对象编程风格。
实际上,基于充血模型的 DDD 开发模式实现的代码,也是按照 MVC 三层架构分层的。Controller 层还是负责暴露接口,Repository 层还是负责数据存取,Service 层负责核心业务逻辑。它跟基于贫血模型的传统开发模式的区别主要在 Service 层。
在基于贫血模型的传统开发模式中,Service 层包含 Service 类和 BO 类两部分,BO 是贫血模型,只包含数据,不包含具体的业务逻辑。业务逻辑集中在 Service 类中。在基于充血
模型的 DDD 开发模式中,Service 层包含 Service 类和 Domain 类两部分。Domain 就相当于贫血模型中的 BO。不过,Domain 与 BO 的区别在于它是基于充血模型开发的,既包含数据,也包含业务逻辑。而 Service 类变得非常单薄。总结一下的话就是,基于贫血模型的传统的开发模式,重 Service 轻 BO;基于充血模型的 DDD 开发模式,轻 Service 重Domain。
为什么基于贫血模型的传统开发模式如此受欢迎?
开发的系统业务可能都比较简单,简单到就是基于SQL 的 CRUD 操作
充血模型的设计要比贫血模型更加有难度,需要从一开始就要设计好针对数据要暴露哪些操作,定义哪些业务逻辑。而不是像贫血模型那样,我们只需要定义数据,之后有什么功能开发需求,我们就在 Service 层定义什么操作,不需要事先做太多设计
思维已固化,转型有成本。基于贫血模型的传统开发模式经历了这么多年,已经深得人心、习以为常
评论区