关于贫血模型和充血模型

  • 什么是贫血模型?
  • 什么是充血模型?

什么是贫血模型?

贫血模型(Anemic Domain Model)是指开发过程中业务的具体方法不在对应的子业务中实现。
以MVC举例。当前后端分离时,后端大致结构为RSC:
Repository层,用于在和数据库,中间键等交互,属性定义在Entity中,方法实现在Repository。
Service层,使用Repository层提供的方法,实现具体的业务,属性定义在各Bo(Business Object)中,方法实现在Service。
Controller层,负责暴露接口。在需求分析阶段定义的要实现的功能,在这一层抽象成具体方法,属性定义在Vo(View Object)。
这里粘一段争大的代码


////////// Controller+VO(View Object) //////////
public class UserController {
  private UserService userService; //通过构造函数或者IOC框架注入
  
  public UserVo getUserById(Long userId) {
    UserBo userBo = userService.getUserById(userId);
    UserVo userVo = [...convert userBo to userVo...];
    return userVo;
  }
}

public class UserVo {//省略其他属性、get/set/construct方法
  private Long id;
  private String name;
  private String cellphone;
}

////////// Service+BO(Business Object) //////////
public class UserService {
  private UserRepository userRepository; //通过构造函数或者IOC框架注入
  
  public UserBo getUserById(Long userId) {
    UserEntity userEntity = userRepository.getUserById(userId);
    UserBo userBo = [...convert userEntity to userBo...];
    return userBo;
  }
}

public class UserBo {//省略其他属性、get/set/construct方法
  private Long id;
  private String name;
  private String cellphone;
}

////////// Repository+Entity //////////
public class UserRepository {
  public UserEntity getUserById(Long userId) { //... }
}

public class UserEntity {//省略其他属性、get/set/construct方法
  private Long id;
  private String name;
  private String cellphone;
}

什么是充血模型?

领域驱动设计(Domain Driven Design,简称 DDD)主张业务方法要和属性绑定。贫血模型中将属性和方法分离的方式显然不符合面向对象设计的封装原则。同时值得注意的是,当复杂业务变化的时候,因为业务全在service层,修改显然更加复杂,也不符合对修改关闭的原则。DDD将业务划分成更细的粒度,将贫血模型中的Bo替换为Domain。Domain中除了包含业务属性外,还包含业务方法。Service中保留和Repository层交互的方法,和其他Service交互的方法,其他方法全部迁到具体的Domain中去,这样Service会变成一个基本稳定的业务类。

### 领域驱动设计(DDD)中贫血模型充血模型的区别及应用场景 在领域驱动设计(Domain-Driven Design, DDD)中,贫血模型(Anemic Model)充血模型(Rich Model)是两种不同的面向对象设计模式,它们在设计理念、代码结构、可维护性以及适用场景等方面存在显著差异。 #### 贫血模型 贫血模型是一种传统的面向对象设计方式,其特点是领域对象(如POJO、DTO、VO等)仅包含数据属性,而业务逻辑则由服务层(Service Layer)集中处理。这种模型通常与面向过程编程思想更为接近,尽管它使用了类对象的形式,但本质上缺乏封装性行为聚合性。 - **特点**: - 领域对象仅包含属性,不包含业务逻辑。 - 所有行为业务规则集中在服务类中。 - 便于理解,适合简单业务场景。 - 与传统MVC、Spring等框架结构兼容性较好。 - **缺点**: - 违背面向对象设计原则,尤其是封装性。 - 随着业务复杂度上升,服务层变得臃肿且难以维护。 - 不利于业务逻辑的复用扩展。 - **应用场景**: - 简单业务逻辑或数据驱动型系统。 - 团队对面向对象设计理解较浅或习惯于面向过程开发。 - 快速原型开发或临时性项目。 #### 充血模型 充血模型是DDD推荐的设计方式,强调将业务逻辑封装在领域对象内部,使对象具备状态行为的统一性。这种方式更符合面向对象的核心理念,能够更好地表达业务规则语义。 - **特点**: - 领域对象包含属性行为,业务逻辑封装在对象内部。 - 更好的封装性高内聚性。 - 更易于维护、扩展测试。 - 更贴近现实世界的业务模型。 - **优点**: - 提高代码的可读性可维护性。 - 更好的复用性扩展性。 - 有助于实现业务逻辑与数据的统一。 - **缺点**: - 对设计人员的抽象能力面向对象思维要求较高。 - 初期学习曲线陡峭,团队需具备一定DDD实践经验。 - 类可能膨胀,需要合理使用设计模式进行拆分组织。 - **应用场景**: - 复杂业务逻辑、核心业务领域。 - 需要长期维护持续迭代的系统。 - 团队具备良好的面向对象设计能力DDD经验。 #### 比较总结 | 特性 | 贫血模型 | 充血模型 | |------------------|----------------------------------|----------------------------------| | 数据与行为分离 | 是 | 否 | | 是否符合OOP原则 | 否 | 是 | | 可维护性 | 差 | 好 | | 适用复杂度 | 简单业务 | 复杂业务 | | 学习与实现成本 | 低 | 高 | | 团队要求 | 对面向对象理解要求低 | 需具备良好的抽象设计能力 | #### 示例代码:充血模型中的订单对象 ```python class Order: def __init__(self, order_id, customer, items): self.order_id = order_id self.customer = customer self.items = items self.status = 'created' def calculate_total(self): return sum(item.price * item.quantity for item in self.items) def apply_discount(self, discount_rate): total = self.calculate_total() discounted_total = total * (1 - discount_rate) return discounted_total def confirm_order(self): if not self.items: raise ValueError("Order must have at least one item.") self.status = 'confirmed' ``` 上述代码中,`Order`类不仅包含属性,还封装了计算总价、应用折扣、确认订单等业务逻辑,体现了充血模型的设计思想。 --- ####
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值