商品领域ddd_DDD领域驱动设计实战详解(一 核心概念)

02402343d1a719c8f2532066f0a1e72b.png
设计不只是感观,设计就是产品的工作方式。——Steve Jobs
相信很多小伙伴,或多或少都会对DDD,有过一定的了解,但总是感觉像天书一样,不知道如何下手,或许也看过很多关于 DDD 的文章, 也买过一些书籍, 但是发现内容冗长, 同时讲解的也不够系统,导致我们的知识体系总是零散的,无法串联起来,在遇到实际项目时 不知道该如何入手,由于 DDD 不是一套框架,而是一种架构思想,所以在代码层面缺乏了足够的约束,导致 DDD 在实际应用中上手门槛很高,甚至可以说绝大部分人都对 DDD 的理解有所偏差,就算已经在项目中使用的人,每个人的理解也不一样。
后续我会整理一系列的文章,从不同的角度对DDD在实际项目中如何落地进行说明,希望可以帮助到大家,同时让DDD的架构思想能够得到推广

本篇博文作为第一篇,给大家从整体的概念上介绍下DDD,让大家先有个全局的认识,这里我借用了一些其他博客的内容,这里进行了一定的整理,希望能够形成一个系统的系列。

DDD初识

DDD(Domain-Driven Design 领域驱动设计)是由Eric Evans最先提出,目的是对软件所涉及到的领域进行建模,以应对系统规模过大时引起的软件复杂性的问题。整个过程大概是这样的,开发团队和领域专家一起通过 通用语言(Ubiquitous Language)去理解和消化领域知识,从领域知识中提取和划分为一个一个的子领域(核心子域,通用子域,支撑子域),并在子领域上建立模型,再重复以上步骤,这样周而复始,构建出一套符合当前领域的模型。

83e9294f41c4c93dac87f2d138c445e8.png

DDD 的相关术语与基本概念

讨论完宏观概念以后,让我们来认识一下 DDD 的一些名词的概念。

统一语言:定义上下文的含义。它的价值是可以解决交流障碍,不管你是 RD、PM、QA 等什么角色,让每个团队使用统一的语言(概念)来交流,甚至可读性更好的代码。 通用语言包含属于和用例场景,并且能直接反应在代码中。 可以在事件风暴(开会)中来统一语言,甚至是中英文的映射、业务与代码模型的映射等。可以使用一个表格来记录。

限界上下文:定义上下文的边界。领域模型存在边界之内。对于同一个概念,不同上下文会有不同的理解,比如商品,在销售阶段叫商品,在运输阶段就叫货品。 首先我们在描述领域时,必定会提到“限界上下文”,简单理解就是领域所处的环境以及邻域处理问题的边界。理论上,限界上下文的边界就是微服务的边界,因此,理解限界上下文在设计中非常重要。

bfde01611523d666138b64ad32c2e4c6.png

领域:领域就是范围。范围的重点是边界。领域的核心思想是将问题逐级细分来减低业务和系统的复杂度,这也是 DDD 讨论的核心。领域既可以表示整个业务系统,也可以表示某个核心子域或者支持子域。可以简单的理解为一个比较完整的含有自己属性和行为的大对象(虽然不恰当,但是辅助理解吧)。在微服务体系中可以理解为一个微服务(我们微服务拆分,通常也是以领域为概念来拆分的,他们两个可以相互理解)。

子域:领域可以进一步划分成子领域,即子域。这是处理高度复杂领域的设计思想,它试图分离技术实现的复杂性。这个拆分的里面在很多架构里都有。

核心域:在领域划分过程中,会不断划分子域,子域按重要程度会被划分成三类:核心域、通用域、支撑域。决定产品核心竞争力的子域就是核心域,是业务成功的主要促成因素,没有太多个性化诉求。桃树的例子,有根、茎、叶、花、果、种子等六个子域,不同人理解的核心域不同,比如在果园里,核心域就是果是核心域,在公园里,核心域则是花。有时为了核心域的营养供应,还会剪掉通用域和支撑域(茎、叶等)。

通用域:如果一个子域被应用于整个业务系统,被多个子域使用的通用功能就是通用域,没有太多企业特征,比如权限认证。

支撑域:对应着业务的某些重要方面,但不是核心,对于功能来讲是必须存在的,但它不对产品核心竞争力产生影响,也不包含通用功能,有企业特征,不具有通用性,比如数据代码类的数字字典系统。

聚合:聚合概念类似于你理解的包的概念,每个包里包含一类实体或者行为,它有助于分散系统复杂性,也是一种高层次的抽象,可以简化对领域模型的理解。
拆分的实体不能都放在一个服务里,这就涉及到了拆分,那么有拆分就有聚合。聚合是为了保证领域内对象之间的一致性问题。
在定义聚合的时候,应该遵守不变形约束法则:

  1. 聚合边界内必须具有哪些信息,如果没有这些信息就不能称为一个有效的聚合;
  2. 聚合内的某些对象的状态必须满足某个业务规则:
  • 一个聚合只有一个聚合根,聚合根是可以独立存在的,聚合中其他实体或值对象依赖与聚合根。
  • 只有聚合根才能被外部访问到,聚合根维护聚合的内部一致性。

聚合根:一个上下文内可能包含多个聚合,每个聚合都有一个根实体,叫做聚合根,一个聚合只有一个聚合根。

实体 Domain 或 entity。《领域驱动设计模式、原理与实践》一书中讲到,实体是具有身份和连贯性的领域概念,可以看出,实体其实也是一种特殊的领域,这里我们需要注意两点:唯一标示(身份)、连续性。两者缺一不可。
你可以想象,文章可以是实体,作者也可以是,因为它们有 id 作为唯一标示。

值对象:为了更好地展示领域模型之间的关系,制定的一个对象,本质上也是一种实体,但相对实体而言,它没有状态和身份标识,它存在的目的就是为了表示一个值,通常使用值对象来传达数量的形式来表示。比如 money,让它具有 id 显然是不合理的,你也不可能通过 id 查询一个 money。定义值对象要依照具体场景的区分来看,你甚至可以把 Article 中的 Author 当成一个值对象,但一定要清楚,Author 独立存在的时候是实体,或者要拿 Author 做复杂的业务逻辑,那么 Author 也会升级为聚合根。

今天就先描述这么多,还有一些概念,我后续会整理出来并更新到这篇文章里例如:上下文映射图、CQRS、领域服务、领域事件、模块、工厂、资源库、集成限界上下文等。

后续会整理成代码,结合代码在做进一步的说明。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值