DDD系列:四、领域层设计规范

这篇具有很好参考价值的文章主要介绍了DDD系列:四、领域层设计规范。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

   在一个DDD架构设计中,领域层的设计合理性,会直接影响整个架构的代码结构以及应用层、基础设施层的设计。但不同业务的领域层设计是需要不断思考和演进的,既要避免未来的扩展性差,又要确保不会过度设计导致复杂性。

传统OOP的缺陷:

  1. extends导致的强依赖父类对象行为,子类若重写父类方法时,违反OCP、里氏替换原则
  2. open for extension可以通过extend语法实现,但close for modified比较难实现,但可以考虑通过组合来实现扩展性(即将新增一个类,将两者的类组合起来)。
  3. 各个对象行为划分问题,某个行为可能影响多个对象,那么其业务逻辑实现应该在哪里?
  4. 多个对象有相同行为时,会有重复的代码,在两个对象中存在,如何维护

设计规范

Entity 实体类设计规范

   Entity中,包含了一个领域的状态和对这个领域的操作。Entity的设计,应当保证实体的不变性,这里所说的不变性指的是Entity在初始化或接受任何操作后,内部的属性没有一致性或冲突问题。

1. 创建即一致

   保证业务流程中,拿到的Entity属性是完整且有效的。为了达到这个效果,建议Entity的创建使用下面两种方式:

使用constructor创建Entity,对所有属性进行初始化

   该方案中,可能导致业务使用时,对Entity construct中,传入过多的参数,如:

Weapon weapon=new Weapon(name,null,weaponTypeEnum,weaponHealth,buffer)

使用Factory模式来创建Entity,降低创建的复杂度

   将初始化动作用Factory来完成,业务只需要传入特有的变化数据。如:

Weapon weapon=WeaponFactory.createWeaponFromEmptyId(name,WeaponPrototype weaponPrototype);

2. 使用Entity的行为对方法进行命名,替代public setter

   传统的public setter,只对Entity中某个属性值进行变更,非常容易打破Entity中的一致性。如订单Entity中,如果只是用setter修改订单状态,那么内部关联的子订单就有可能出现不一致的情况。

public class Weapon{
	int  damageType;
  
  /**
  在DDD模式下,setter更名为changeDamageTo更合理,且方法中可以对相关联的属性进行设值
  **/
  public void setDamageType(int type){
    this.damageType=damageType;
  }
  
}

3. 不强依赖外部的领域服务或聚合根

   原因:Entity依赖(指的是Entity属性中的依赖)外部的 DomainService 或聚合根时,当前Entity 无法保证依赖对象变更后,自己内部的数据是否还具有正确性和一致性。

正确的对外部依赖的方法有如下两个:

  • Entity中依赖外部DomainServie的id,这个id建议是强类型的id,非Long型的id。因为强类型的id可以包含校验动作,可以在entity构建时,和其他基础类型区分开。
  • 通过入参的方式,传入外部DI的Service服务,如equip(Weapon, EquipmentService)

Domain Service 领域服务设计规范

需要使用domain service的原则:

  1. 操作多个entity,确保多个实体的变更具有一致性
  2. 要使用托管的第三方服务来操作Entity
  3. 通用组件,多个Entity都具有的某个行为

思考

如何判断 Entity 设计是否合理?

  1. 是否符合业务概念:Entity应该反映出业务中的实体概念、重要信息,并且能够正确地表达实体之间的关系和属性
  2. 是否具有可测试性:Entity 应该具有可测试性,能够通过自动化测试来验证其正确性。
  3. 内部一致性:创建的 Entity 应当保证内部数据的合理、有效,Entity 对外提供的操作,也应当保证该原则。

随笔

ECS(Entity-Component-system)架构的优点:

  • 组件化:将数据的变化和行为,拆分为不同的组件,实现组件化,降低系统复杂度

  • 行为抽离:即将通用的行为,做到公共的模块中

  • 数据驱动:对象的行为由数据驱动,通过数据驱动+组件化,让对象的行为可根据数据实时变化

DDD下各个层级应当承载的内容

Interface层

   Interface层通常返回统一的Result模型或其子模型,包装所有从Application、domian、infrastructure层抛出的异常。

接口层组成的功能:

   完成鉴权、session校验、接口统一日志、限流、统一接口返回内容、前置缓存、异常统一管理等内容。

接口定义的数量和业务隔离问题:

   在接口层面,当把多个类似的业务,做到同一个接口中时,容易出现参数膨胀,所以在设计接口时,考虑Single Responsibility Principle,若不同的接口有相同的一些操作,需要下沉到Application Service层中去。

   接口层直接对接业务,可以快速的变化,但我们希望ApplicationService层的调整比较小,Domain层几乎没有变化。

Application层

核心内容:

  1. ApplicationService:业务服务编排层,理论上讲,不承接业务,但对领域模型的构建要求较高,所以,可以运行ApplicationService承接部分非核心的、非通用的业务逻辑
    • 服务编排和业务逻辑的区分,需要看具体的代码逻辑来界定,没有一个非常明确的定义。
  2. DTO Assemble:将内部领域模型向DTO转换
  3. 入参由Command、Query、Event组成
  4. 出参为DTO
  5. 不负责处理异常,由上层统一完成处理

Command、Query、Event的应用

Command Query Event 单一的入参,如Id
语义 待执行的一个命令 查询动作 已经发生的一个事件 对这个id做某个动作
返回内容 DTO、Boolean DTO void void

为什么需要CQE对象

  1. 由于业务的发展,方法的入参会越来越多,导致阅读困难、在使用时容易把同类型的入参位置填错
  2. CQE中,可以对对象中的字段进行校验,避免简单的校验逻辑,出现在application Service中。
    • 如果在使用已存在的CQE时,发现CQE对象中的校验在新的业务场景不合适时,那么说明这个是两个业务,需要再建一个不同的CQE对象,其命名与老的区分开。

Infrastructure层

   利用Anti-Corruption Layer,将外部的透出的模型,转为应用内部的数据模型,屏蔽外部接口变化对应用内业务代码的影响。文章来源地址https://www.toymoban.com/news/detail-431523.html

到了这里,关于DDD系列:四、领域层设计规范的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【实践篇】领域驱动设计:DDD工程参考架构

    不同团队落地DDD所采取的应用架构风格可能不同,并没有统一的、标准的DDD工程架构。有些团队可能遵循经典的DDD四层架构,或改进的DDD四层架构,有些团队可能综合考虑分层架构、整洁架构、六边形架构等多种架构风格,有些在实践中可能引入CQRS解决读模型与写模型的差异

    2024年02月05日
    浏览(48)
  • 软件架构演进过程与微服务设计中的领域驱动设计(DDD)

    软件架构的演进是一个不断改进和解决问题的过程。从传统架构到面向服务架构(SOA),再到微服务架构,每个阶段都带来了新的技术和解决方案。而在微服务架构中,领域驱动设计(DDD)起着至关重要的作用,它能够提高系统的可扩展性、可维护性和可理解性。本文将介绍软件架

    2024年02月16日
    浏览(42)
  • 快速理解DDD领域驱动设计架构思想-基础篇 | 京东物流技术团队

    本文与大家一起学习并介绍领域驱动设计(Domain Drive Design) 简称DDD,以及为什么我们需要领域驱动设计,它有哪些优缺点,尽量用一些通俗易懂文字来描述讲解领域驱动设计,本篇并不会从深层大论述讲解落地实现,这些大家可以在了解入门后再去深层次学习探讨或在后续进阶

    2024年02月09日
    浏览(41)
  • 领域驱动设计——DDD领域驱动设计进阶

    进阶篇主要讲解领域事件、DDD 分层架构、几种常见的微服务架构模型以及中台设计思想等内容。如何通过领域事件实现微服务解耦?、怎样进行微服务分层设计?、如何实现层与层之间的服务协作?、通过几种微服务架构模型的对比分析,让你了解领域模型和微服务分层的作

    2024年01月15日
    浏览(49)
  • DDD领域设计理解

    目录 DDD 领域驱动设计理解(Domain Driven Design) 概念 核心 目标 领域驱动设计事实上是1针对OOAD的一个扩展和延申。DDD基于面向对象分析与设计技术。 对技术架构进行了分层规划。 对每个类进行了策略和划分。 OOAD 面向对象设计的扩展和延申,多了domain的概念就是需求分析和

    2024年04月10日
    浏览(32)
  • DDD领域驱动设计(六)

    领域对象需要资源存储。存储手段多样化,常见就是数据库,分布式缓存,localCache.资源库的作用,就是对领域的存储和访问进行统一管理对象。在抽奖平台中。通过下面这种方式组织资源库。

    2024年01月24日
    浏览(69)
  • 领域驱动设计DDD实际项目落地最佳实践

    领域驱动设计(Domain Driven Design,简称:DDD)设计思想和方法论早在2005年时候就被提出来,但是一直没有被重视和推荐使用,直到2015年之后微服务流行之后,再次被人重视和推荐使用。 下面我来介绍一下DDD设计思想和方法论,同时结合我们在实际项目中应用总结和思考。 目录

    2024年02月08日
    浏览(60)
  • 万字长文助你上手软件领域驱动设计 DDD

    最近看了一本书《解构-领域驱动设计》,书中提出了领域驱动设计统一过程(DDDRUP),它指明了实践 DDD 的具体步骤,并很好地串联了各种概念、模式和思想。因此,我对书本内容做了梳理、简化,融入自己的理解,并结合之前阅读的书籍以及实践经验,最终形成这篇文章。

    2024年02月08日
    浏览(42)
  • 二代水务系统架构设计分享——DDD+个性化

    C/S架构的单体桌面应用,可以满足客户个性化需求,易于升级和维护。相比于一代Winform,界面要求美观,控件丰富可定制。 依托.Net6开发平台,采用模块化思想设计(即分而治之的策略),每个模块采用DDD分层设计。前端选用WPF + Prism框架,后端选用ABP + EF框架,数据库选择SQ

    2024年02月14日
    浏览(41)
  • DDD脚手架及编码规范

    一、背景介绍 我们团队一直在持续推进业务系统的体系化治理工作,在这个过程中我们沉淀了自己的DDD脚手架项目。脚手架项目是体系化治理过程中比较重要的一环,它的作用有两点: 可以对新建的项目进行统一的规范 对于指导老项目进行DDD的改造提供指导 本文主要是梳理

    2024年02月08日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包