有了MVC,为什么还要DDD?_ddd架构和mvc架构区别_倾听铃的声的博客-CSDN博客
2.浅析VO、DTO、DO、PO的概念、区别和用处
-
DO(Domain Object):表示领域对象,是指应用程序中与业务流程直接相关的对象。DO通常体现应用程序的核心领域模型,比如订单、商品、用户等。它们通常是通过面向对象编程语言定义的类实现的,包含该领域模型特有的属性和方法。 不写业务逻辑,业务逻辑放在BO中,单纯是个POJO
- 例如,一个电商网站中的Order类,代表了订单的领域模型,具有属性(订单号、下单时间、收货人信息等)和方法(创建订单、支付、发货等)。
-
BO(Business Object):表示业务对象,是指封装了业务逻辑处理的对象。BO主要负责管理DO,并且通常包含一些复杂的业务逻辑处理。BO常常作为服务提供方,外部系统可以调用BO提供的服务来执行某些具有业务意义的操作。
- 例如,在一个在线教育平台中,CourseBO类代表了课程业务对象,它除了封装了CourseDO对象,还包含了一些处理业务逻辑的方法,比如发布课程、修改课程状态等。外部系统可以通过调用CourseBO类提供的服务来执行相关操作。
-
DTO(Data Transfer Object):表示数据传输对象,是指在不同层之间传输数据时使用的对象,主要作用是简化数据传输的复杂度和提升传输效率。DTO通常只包含数据,不包含任何业务处理逻辑。
- 例如,在电商网站中,OrderDTO类代表了订单的数据传输对象,在不同的层之间进行数据传输。它只包含了OrderDO对象中需要传输的属性,而没有与业务逻辑相关的方法。
-
VO(Value Object):表示值对象,是指在具有某一特定行为或属性的情况下只保存其值的对象。VO通常是DTO的一部分,用于在不同层之间传递数据。
- 例如,在一个电商网站中,AddressVO类代表了收货地址的值对象,在不同层之间进行数据传输,包含了收货地址的相关属性,但不包含任何业务逻辑处理。
-
PO(Persistent Object):表示持久化对象,是指与数据库表中的记录相对应的对象,在ORM框架中经常出现。PO通常包含了数据持久化相关的信息,比如数据表中的字段映射信息、主键信息等。
- 例如,在电商网站中,OrderPO类代表了订单的持久化对象。它与数据库中的订单表相对应,包含了订单表中的字段映射信息、主键信息等。
个人觉得应该这样分层:
VO放在表示层
DTO放在应用层
DO放在领域层 BO代表聚合根BO 写业务逻辑
PO 放在基础设施层 对应数据库
3.充血模型和贫血模型
充血模型(Rich Model)和贫血模型(Anemic Model)是两种常见的领域模型设计方式,它们之间最重要的区别在于业务逻辑的处理方式和数据和行为的分离程度。
充血模型是指领域对象(Domain Object)具有完整的数据和行为,即业务逻辑通过领域对象本身来实现。在这种模型中,领域对象包含了丰富的业务逻辑和状态,并封装了对自身状态的管理和操作。例如,在一个订单聚合内部,订单对象不仅包含了订单的基本属性,还包含了计算订单总价、验证订单状态等一系列业务逻辑。
贫血模型则是指领域对象只保留了数据,而将业务逻辑放置在外部服务中实现,这使得领域对象成为了一个“被动”的数据结构。在这种模型中,领域对象主要用于封装和传输数据,而业务逻辑通常由其他组件(例如控制器、服务等)来处理。例如,在一个订单聚合内部,订单对象只包含了基本的订单属性,而相关的业务逻辑则由外部服务或控制器来实现。
两种模型各有优缺点,根据具体业务场景和需求进行选择:
- 充血模型通过封装领域对象内部的状态和行为,可以更好地保证领域对象的一致性和正确性,并提高整个系统的可维护性和可测试性。但是,由于业务逻辑的复杂性,可能会导致领域对象过于臃肿,容易引起设计上的问题。
- 贫血模型通过将业务逻辑从领域对象中分离出来,可以使得代码更加简洁和灵活,并且容易进行重构和扩展。但是,它也容易违反面向对象编程的原则和领域建模的规范,可能会导致“过度工程化”的问题。
需要注意的是,在实际应用中,充血模型和贫血模型并不是绝对的两极,而是存在一些中间状态。在具体设计时,我们应该根据需求和团队经验进行综合考虑,选择最适合当前应用场景的模型。