设计模式之美学习-传统MVC和DDD充血模型(二)
贫血模型
贫血模型例子
现在传统的MVC开发基本上都是贫血模型 如以下代码 我们工作中经常使用
////////// 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; }
我们将所有业务逻辑都写在servcie里面 将BO和业务逻辑根据service分离开了,这是一种面向过程的风格开发方式
充血模型
什么是充血模型
在贫血模型中,数据和业务逻辑被分割到不同的类中。充血模型(Rich Domain Model)正好相反,数据和对应的业务逻辑被封装到同一个类中。因此,这种充血模型满足面向对象的封装特性,是典型的面向对象编程风格
什么是领域驱动设计
主要用来指导如何解耦业务系统,划分服务模块,定义业务领域模型及其交互 早在2014年就剔除,真正兴起是在微服务兴起的时候.微服务需要根据公司业务对服务进行合理的划分。而ddd正好可以做到指导的作用
实际上DDD也是传统的MVC三层 在service加了一层doman 跟贫血不一样的是 BO除了包含数据 还包含了对应数据的业务处理
贫血模型:重Service 轻Bo 充血模型:轻Service 重Bo
为什么基于贫血模型的传统开发模式如此受欢迎
- 大部分公司业务都比较简单,就算基于充血模型设计 模型也比较单薄 ,与其绞尽脑汁设计充血模型不如直接使用贫血模型。而且业务也经常变 或者整体推翻重做
- 充血模式比贫血更加有难度,充血模型 是根据模型定义要暴露哪些操作 而不是贫血模型 我们先定义好数据表结构 然后根据数据表结构有哪些业务 就在service添加对应处理业务的方法
- 思维固化现在基本上的程序开发都是贫血模型 开发人员也是使用贫学模型,如果使用充血模型学习成本增加
什么项目应该考虑使用基于充血模型的 DDD 开发模式
业务复杂的项目应该优先考虑使用DDD开发模式
因为贫血模型 我们是基于业务再service定义个对数据表CRUD的操作,对业务耦合性比较大,无法重用,
而基于ddd则是根据模型定义好要暴露的操作 然后在service根据业务使用这些暴露的操作完成一系列业务,复用性更强 越复杂的系统对重用性以及易维护性要求更强
充血模型例子
目前公司采用的就是DDD例子如下
在DDD下操作数据对象都是操作通过聚合根操作的,聚合操作的。在domain这一层比如发货为例子
com.yxt.assist.toolkit.server.coldchain.transport.shipment.domain.service.impl.ColdChainShipmentOrderDomainServiceImpl#doSaveBatchShipOrder
com.yxt.assist.toolkit.server.coldchain.transport.shipment.domain.model.ColdChainShipmentOrderAggregate#shipOrder
我们在看一下这个聚合根下的其他方法就容易理解充血模型了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!