欢迎继续关注本系列文章,下面我们继续讲解下DDD在实战落地时候,会具体碰到哪些问题,以及解决的方式有哪些。

DDD 是一种思想,主要知道我们方向,具体如何做,需要我们根据业务场景具体问题具体分析。

充血模型和实体Spring注入问题

在领域驱动设计(DDD)中,充血模型是一种常见的模型设计方式,其中领域对象(实体和值对象)包含了业务逻辑和状态,并且负责自己的行为。在Spring框架中,如果你想使用充血模型,并且需要依赖其他服务或组件, 在现在的Java开发中基本上都离不开Spring的框架,每个领域服务和公共服务都转换成Spring的bean对象,我们创建领域对象的时候采用new关键字创建对象,这样就会导致实体中的bean对象无法注入。举例如下:

@Data
public class PersonDO {
@Autowired
PersonService personService; private String personName;
private String personAge;
}

在这种情况下我们无法注入 personService 对象,方式有两种:

  1. 使用spring ApplicationContextAware 获取容器中的对象
  2. 在使用时,把personService 作为参数传入。

这两个方式,我更偏向第一种,这样我们就可以直接在实体中使用Spring的对象,不必依赖调用方。

大聚合根的加载性能问题

大聚合根的加载性能问题是在领域驱动设计 (DDD) 中常见的挑战之一。当一个聚合根包含大量关联实体或值对象,并且需要在应用程序中频繁加载和操作这些关联对象时,可能会导致性能下降。以下是一些解决大聚合根加载性能问题的策略和最佳实践:

  1. 按需加载(Lazy Loading): 采用按需加载的策略,只在需要的时候加载相关对象,而不是一次性加载整个聚合根及其所有关联对象。这可以通过延迟加载技术来实现,确保只有在首次访问关联对象时才加载它们。
  2. 分页加载: 如果可能的话,将大聚合根的关联对象分为多个分页加载,而不是一次性加载所有对象。这可以减轻数据库或持久层的负担,并提高性能。
  3. 缓存: 使用缓存来存储已加载的聚合根和关联对象,以减少数据库查询的次数。缓存可以是内存缓存,如EhCache或Redis,也可以是分布式缓存,具体根据应用程序需求而定。
  4. 事件驱动架构: 在DDD中,可以使用事件驱动架构,当聚合根发生变化时,发布事件通知其他部分。这样,其他部分可以在需要时获取相关数据,而不必依赖于大聚合根的加载。

领域代码爆炸问题

领域代码爆炸问题指的是在采用领域驱动设计(DDD)时,领域层的代码变得非常庞大和复杂,难以维护和管理的情况。这种问题通常发生在领域模型非常复杂或领域规模非常庞大的情况下。以下是一些可能导致领域代码爆炸问题的原因以及相应的解决方案:

  1. 复杂的领域逻辑: 领域模型中包含大量复杂的业务规则和逻辑,导致领域层的代码变得庞大。
  2. 领域对象过多: 如果你的领域模型中有大量的实体、值对象和聚合根,就会导致领域层的代码量增加。
  3. 领域的多样性: 当一个领域内包含多个不同的子领域或业务概念时,可能需要处理多样性的业务逻辑,增加了代码复杂度。
  4. 领域的增长: 随着业务的增长和演化,领域模型可能会变得越来越复杂,导致代码爆炸问题。

解决方案:

  1. 分解领域模型: 将复杂的领域模型分解成更小的部分,每个部分专注于特定的子领域或业务概念。这可以通过子域划分和领域内的模块化来实现。
  2. 聚合设计: 合理设计聚合,将相关的实体和值对象组合成聚合根。聚合应该有清晰的界限,每个聚合负责管理自己的一致性。
  3. 领域服务: 将一些通用或复杂的领域逻辑抽象为领域服务,这些服务可以跨多个聚合和实体使用,减少了重复的代码。
  4. 模块化开发: 将领域层的代码模块化,每个模块负责不同的子领域或功能。这有助于分散代码的复杂性。
  5. 领域事件: 使用领域事件来解耦领域内的业务逻辑。领域事件可以用于发布和订阅领域内的变化,从而减少对象之间的直接依赖。

DDD,微服务和中台的关系

领域驱动设计(DDD)、微服务架构和中台架构是三个关键的软件架构和设计概念,它们在现代软件开发中扮演着重要角色。以下是它们之间的关系:

  1. DDD(领域驱动设计): DDD 是一种软件设计方法,着重于理解和建模业务领域。它强调将业务领域建模成具体的领域对象、实体、值对象和聚合根等概念。DDD 提供了一种方法来创建复杂业务逻辑的领域模型,并将其映射到软件中。DDD 强调的是如何正确地表达业务需求和规则,使软件更好地满足业务要求。
  2. 微服务架构: 微服务架构是一种将应用程序拆分成小的、独立的服务的方法。每个微服务负责处理一个特定的业务功能,并可以独立开发、部署和扩展。微服务的设计目标是提高系统的灵活性、可维护性和可扩展性。微服务通常与 DDD 结合使用,每个微服务可能包含一个或多个领域,将 DDD 领域模型映射到微服务中。
  3. 中台架构: 中台架构是一种将通用功能和服务集中到中心位置以供多个应用程序或业务领域使用的方法。中台的目标是提供跨多个应用共享的核心功能,减少重复开发和维护。中台可以包括身份认证、支付、消息队列、缓存等通用功能。中台架构也可以与 DDD 和微服务结合使用,使各个微服务能够共享中台提供的通用功能。

关于它们之间的具体关系:

  • DDD 可以用于更好地理解和建模微服务中的领域,帮助设计微服务的领域模型。
  • 微服务可以根据 DDD 的原则来组织领域对象和业务逻辑,每个微服务可以包含一个或多个领域。
  • 中台架构可以提供通用的支持服务,例如身份验证、日志记录、监控等,以支持微服务的开发和运行。这些通用服务可以在中台中实现,并由微服务共享。

总的来说,DDD、微服务和中台架构都是为了更好地满足复杂业务需求和提高软件系统的灵活性而设计的,它们可以结合使用以创建强大且易于维护的软件系统。选择何种组合方式取决于具体的业务需求和技术环境。

领域的划分原则是什么,怎么划分领域

领域的划分是领域驱动设计(DDD)中的一个关键概念,它有助于组织和建模复杂的业务领域。以下是确定领域划分的一些原则和方法:

  1. 业务上下文: 领域应该基于业务上下文来划分。一个业务上下文代表了一组相关的业务概念、实体、规则和用例,它们在特定领域内具有一致的业务边界。业务上下文通常与组织中的不同部门、团队或子系统相关联。
  2. 限界上下文(Bounded Context): DDD 中引入了限界上下文的概念,它定义了领域的边界和含义。在限界上下文内,领域模型是一致的,而在不同的限界上下文之间,模型可以有不同的含义。通过识别和定义限界上下文,可以明确不同领域之间的边界和交互。
  3. 专业知识和业务专家: 与业务专家密切合作,他们可以提供关于业务领域的深刻理解。借助专业知识,可以更好地识别领域内的核心概念和关键实体,有助于确定领域划分。
  4. 关注点分离: 领域划分应该关注业务上下文的不同关注点。例如,一个电子商务系统可以包括订单管理、库存管理和用户管理等不同的领域,每个领域关注不同的业务问题。
  5. 复杂性和可维护性: 领域划分也可以考虑系统的复杂性和可维护性。将大型系统分解成更小的领域可以降低单个领域的复杂性,并使系统更易于维护和扩展。
  6. 领域边界的清晰性: 领域划分应该具有清晰的边界,以便在不同领域之间进行明确的交互和集成。这有助于避免混淆和冲突。
  7. 可扩展性: 随着业务的增长,领域应该能够灵活扩展。划分领域时,考虑未来的业务需求和变化。

总结

本文介绍了在实际应用领域驱动设计(DDD)时可能遇到的一些常见问题以及解决方案。首先,讨论了在采用充血模型时,如何在Spring框架中进行依赖注入的问题,提供了两种解决方法,其中一种是使用Spring的ApplicationContextAware接口,另一种是将依赖作为参数传递,以确保领域对象可以访问所需的服务和组件。

其次,探讨了大聚合根的加载性能问题,特别是当一个聚合根包含大量关联实体或值对象时,可能导致性能下降的情况。为了解决这个问题,建议采用按需加载、分页加载、缓存和事件驱动架构等策略,以提高大聚合根的加载和操作性能。

接着,提到了领域代码爆炸问题,即领域层的代码变得庞大和复杂,难以维护和管理的情况。为应对这一挑战,建议采用分解领域模型、合理设计聚合、使用领域服务、模块化开发和领域事件等方法,以减轻领域代码的复杂性。

最后,讨论了DDD、微服务和中台架构之间的关系,强调它们可以结合使用以创建强大且灵活的软件系统,具体选择取决于业务需求和技术环境。

通过本文的内容,读者可以更好地理解DDD在实际项目中的应用,并掌握应对相关挑战的方法和策略。在实施DDD时,务必根据具体情况灵活运用这些解决方案,以满足业务需求并提高软件质量。

领域驱动设计(DDD):DDD落地问题和一些解决方法的更多相关文章

  1. 领域驱动设计(DDD)部分核心概念的个人理解

    领域驱动设计(DDD)是一种基于模型驱动的软件设计方式.它以领域为核心,分析领域中的问题,通过建立一个领域模型来有效的解决领域中的核心的复杂问题.Eric Ivans为领域驱动设计提出了大量的最佳实践 ...

  2. 领域驱动设计(DDD)部分核心概念的个人理解(转)

    领域驱动设计(DDD)是一种基于模型驱动的软件设计方式.它以领域为核心,分析领域中的问题,通过建立一个领域模型来有效的解决领域中的核心的复杂问题.Eric Ivans为领域驱动设计提出了大量的最佳实践 ...

  3. 一次领域驱动设计(DDD)的实际应用

    笔者先前参与了一个有关汽车信息的网站开发,用于显示不同品牌的汽车的信息,包括车型,发动机型号,车身尺寸和汽车报价等信息.在建模时,我们只需要创建名为Car的实体(Entity)对象.其他的信息,比如车 ...

  4. 领域驱动设计(DDD)的实际应用

    领域驱动设计(DDD)的实际应用   笔者先前参与了一个有关汽车信息的网站开发,用于显示不同品牌的汽车的信息,包括车型,发动机型号,车身尺寸和汽车报价等信息.在建模时,我们只需要创建名为Car的实体( ...

  5. 领域驱动设计(DDD)的实践经验分享之ORM的思考

    原文:领域驱动设计(DDD)的实践经验分享之ORM的思考 最近一直对DDD(Domain Driven Design)很感兴趣,于是去网上找了一些文章来看看,发现它确实是个好东西.于是我去买了两本关于 ...

  6. 领域驱动设计(DDD)的实践经验分享之持久化透明

    原文:领域驱动设计(DDD)的实践经验分享之持久化透明 前一篇文章中,我谈到了领域驱动设计中,关于ORM工具该如何使用的问题.谈了很多我心里的想法,大家也对我的观点做了一些回复,或多或少让我深深感觉到 ...

  7. 领域驱动设计(DDD)在美团点评业务系统的实践

    前言 至少 30 年以前,一些软件设计人员就已经意识到领域建模和设计的重要性,并形成一种思潮,Eric Evans 将其定义为领域驱动设计(Domain-Driven Design,简称 DDD).在 ...

  8. .NET领域驱动设计—看DDD是如何运用设计模式颠覆传统架构

    阅读目录: 1.开篇介绍 2.简单了解缘由(本文的前期事宜) 3.DomainModel扩展性(运用设计模式设计模型变化点) 3.1.模型扩展性 3.2.设计模式的使用(苦心专研的设计模式.设计思想可 ...

  9. 基于“事件”驱动的领域驱动设计(DDD)框架分析

    摘抄自 从去年10月份开始,学了几个月的领域驱动设计(Domain Driven Design,简称DDD).主要是学习领域驱动设计之父Eric Evans的名著:<Domain-driven ...

  10. [转] .NET领域驱动设计—看DDD是如何运用设计模式颠覆传统架构

    阅读目录: 1.开篇介绍 2.简单了解缘由(本文的前期事宜) 3.DomainModel扩展性(运用设计模式设计模型变化点) 3.1.模型扩展性 3.2.设计模式的使用(苦心专研的设计模式.设计思想可 ...

随机推荐

  1. 密码暴力破解工具——九头蛇(hydra)使用详解及实战

    转载出处:https://zhuanlan.zhihu.com/p/540998739 二.使用方法 语法:Hydra 参数 IP 服务 参数: -l login 小写,指定用户名进行破解 -L fi ...

  2. 【原创】浅谈EtherCAT主站EOE(上)-EOE网络

    这篇文章的标题虽然是关于EtherCAT EOE,但其实主要内容是关于整个EOE网络结构,属于计算机网络原理.而EtherCAT EoE只是简单介绍,并不是文章的重点.需要注意的是,我们的描述主要基于 ...

  3. Groovy 基于Groovy实现MD5加密

    groovy 3.0.7 代码实现 实现方式1 import java.security.MessageDigest; public class MD5Utils { public final sta ...

  4. UpSetR:多数据集绘图可视化处理利器

    说到集合数据可视化,我们第一时间想到的就是韦恩图.在 NGS 相关的研究中,韦恩图用来直观表征不同的集合之间元素重叠关系,是经常在文献中出现的图. 在集合数少的时候韦恩图是很好用的,但是当集合数多比如 ...

  5. 流量劫持 —— GZIP 页面零开销注入 JS

    前言 HTTP 代理给页面注入 JS 是很常见的需求.由于上游服务器返回的页面可能是压缩状态的,因此需解压才能注入,同时为了节省流量,返回下游时还得再压缩.为了注入一小段代码,却将整个页面的流量解压再 ...

  6. mybatis拦截器实现数据权限

    前端的菜单和按钮权限都可以通过配置来实现,但很多时候,后台查询数据库数据的权限需要通过手动添加SQL来实现. 比如员工打卡记录表,有id,name,dpt_id,company_id等字段,后两个表示 ...

  7. 【Rust-book】第五章 使用结构体来组织相关联的数据

    第五章 使用结构体来组织相关联的数据 结构,或者结构体,是一种自定义数据类型,它允许我们命名多个相关的值并将它们组成一个有机的结合体. 可以把结构体视作对象中的数据属性 1 对比元组和结构体之间的异同 ...

  8. Hive常见时间日期函数的使用与问题整理

    这里整理一下Hive常见的时间函数和日期函数和用法,作为平时数据处理过程的一个检索和记录. 平时在数据处理过程中,如果不经常使用时间函数,一时间遇到一些时间上的处理,难免会想不起来. hive本身提供 ...

  9. 自然语言处理 Paddle NLP - 基于预训练模型完成实体关系抽取

    自然语言处理 Paddle NLP - 信息抽取技术及应用 重点:SOP 图.BCEWithLogitsLoss 基于预训练模型完成实体关系抽取 信息抽取旨在从非结构化自然语言文本中提取结构化知识,如 ...

  10. 使用python发送sip协议的OPTIONS

    环境:Windows10_x64  Python版本 :3.9.2   sip协议提供了OPTIONS请求方法可用于探测对端状态,今天记录下Windows10环境下使用python3.9简单实现sip ...