领域驱动设计在讲什么

领域驱动设计在讲什么,第1张

领域驱动设计在讲什么 概述

概念可以简单描述某类事物,这类事物可以是实体也可以是问题。领域驱动设计是为了管理系统复杂性问题而生的一套方法论。

随着业务系统的复杂性不断提高,系统的性能和灵活性要求也会越来越高,如何构建一个扩展性强、可用性高的业务系统是需要我们不断思考的问题。

我们以交易系统为例,在互联网之初,实体商业占据绝对主导地位的时代,电子商务系统最初的目的就是把货物卖出去,业务需求很简单,就是一手付钱,一手交货,而更多的难点是在于如何让人们接受并认可在网络上进行交易。随着这几十年的发展,电商早已不是最初的样子,需求变为如何更快更多的把商品卖出去,于是产生出了层出不穷你算不清楚的促销活动,比如满减、凑单、会员价、拼团、优惠券等。你买东西的价格也许只有系统能真正算清楚。

系统的复杂性比起最初,呈几何倍的增长,如何控制并管理系统复杂度是我们需要在业务发展过程中需要解决的问题。复杂的业务各有各的复杂,而拆解之道也各有各的侧重,今天要介绍的是领域驱动设计如何帮助我们拆解需求,并建立一个灵活性高、可扩展的业务系统。

该内容为作者(知一)原创,首发在个人博客 https://noogel.xyz 和微信公众号『知一杂谈』,欢迎 关注、点赞、留言~

领域驱动设计在讲什么

领域驱动设计中的领域是什么?我理解的是一个比行业更加细分的方向,比如互联网做电商业务是电商领域,电商中有专注交易的交易领域,做电子支付叫支付领域。领域范围可大可小,领域知识表示某些具有相关相关性知识的合集。

领域驱动设计是通过领域知识构建的领域模型来控制业务的复杂性,通过领域模型反映领域知识,构建更易维护的系统。解决软件难以理解,难以演化的问题。

上面的总结涉嫌鸡生蛋蛋生鸡的问题。其实领域模型和领域知识是迭代产生的,随着人类抽象总结而不断凝练而成的。拿之前讨论过的例子来说,一个电商领域专家可能脱口而出订单的概念,大家先入为主的很容易理解这个概念。

从人类历程来看最早出现的是物物交换的概念,后面逐渐变成等价货币交换,我们抽象的名词叫交易,再到后面你从我这里付一笔钱,我给你一个凭据,过段时间你来取货,我们管这叫购买凭据,进而逐渐演化成订单这个概念。

领域驱动设计的核心价值

领域驱动设计的核心目标是基于特定业务范围,通过统一业务概念(统一语言),将系统参与各方整合在一起,从而减少不同角色和环节的信息熵减问题。

领域模型是领域驱动设计的核心产出,它不仅能描述真实的业务逻辑和业务场景,也是系统实现的表达方式。领域模型的适应性能直接反应系统的扩展性上,能否使系统在增大时仍然保持敏捷。

领域驱动设计之所以更加流行,很大因素是领域驱动设计提供的方法论上与近些年流行的微服务有很好的匹配性,通过领域驱动设计方法清晰地识别业务边界,以此来指导微服务的拆分。 领域驱动设计提供的领域划分方法可以指导我们对微服务的拆分,以及对于演进式架构有很强的助力。

领域驱动设计的适用场景

通过上面对于领域驱动设计的介绍,可以提炼出三个主要作用:

    统一通用语言,降低不同角色间的沟通成本。通过战略设计划分子域、限界上下文,以此垂直拆解复杂度。通过聚合的方式进行建模,以此水平拆解复杂度。

通过以上三个作用来逐步介绍领域驱动设计的适用场景。

多角色协作的业务场景

领域驱动设计中引入领域专家角色,是指对某个领域的概念和流程有着深入理解的一类人。开发人员与领域专家之间,他们掌握的知识存在巨大的差异。就比如电商领域专家清楚地了解交易单、订单、子单、售后、物流单、运单这些概念的准确含义,而开发人员更专注技术的运用,在沟通中如果没有达成一致的理解,沟通效率就会很差,甚至产生误解。

领域驱动设计提出从需求中提炼出统一语言,其实就是在两个不同的语言世界中进行正确翻译的过程。在多角色协作的场景中可以有效降低沟通成本,迭代式的探索和发现模型。

复杂业务场景进行业务拆解

上面我们提到现代电商促销方案层出不穷,决定一笔交易的金额有很多影响因素,而算价结果直接影响到这笔交易的支付金额,以及每件商品的实付金额。如果我们认为促销价格计算和交易联系很紧密就把他们放到了一起去开发维护,我想这个系统后面必定会难以维护,最终进行拆分。

而系统拆分的指导思想就是我们耳熟能详的六个字:『高内聚,低耦合。』 领域驱动设计有着一套完整的方法论,指导我们对复杂问题进行拆分、梳理各个子系统间的关系,帮助我们落地复杂系统。

 该内容为作者(知一)原创,首发在个人博客 https://noogel.xyz 和微信公众号『知一杂谈』,欢迎 关注、点赞、留言~

领域驱动设计核心概念

领域驱动设计学习拦路虎之一就是众多的概念,第一次接触这些概念会有一定的理解成本,不过正是这些概念支撑起的领域驱动设计,接下来会以电商为例对其中的核心概念做介绍。

电商案例

网上购物已经成为我们生活中不可分割的一部分,作为一个用户而言我们经历的流程有以下几点:

    从商品列表页面选择需要的商品。查查商品的促销活动,凑凑满减。在购物车选择需要买的商品下单。下完单通过微信或者支付宝付钱。然后等着物流送货上门。

作为电商的管理人员我们需要做的则是以下几点:

    从采购点采购商品,存放到仓库。编辑商品信息,上架售卖。编辑一些优惠信息展示在平台上。将用户下单的商品通知仓库发货。营收成本的清结算。

电商平台作为一个复杂系统主要有多阶段、⻓链路、多角⾊参与、多信息互通的商品/服务交换过程的特点。而领域驱动设计中的概念能支撑我们将电商复杂流程拆解消化,并且建立一个易扩展、更稳定的系统。

通用语言和限界上下文

既然有多方协作参与系统的建设和运营,就需要沟通,而降低沟通成本的一个关键就是统一概念和认知,比如我们对于商品的认知,同样都是 iPhone 13,蓝色和粉色,128G 和 256G ,我们说卖掉了一个 iPhone 13 还是卖掉了一个 iPhone 13 蓝色 256G 要怎么表达,这时我们需要有两个概念 SKU 和 SPU 来区分,SKU 作为商品最小售卖单元表达后者,SPU 作为商品信息聚合的最小单位表达前者。

正是因为不同参与角色可能有不同的理解,为了降低大家沟通的障碍,提出了通用语言和限界上下文这两个重要概念。

使团队交流达成共识的能够明确简单清晰地描述业务规则和业务含义的语言就是通用语言。 解决各岗位的沟通障碍问题,促进不同岗位的和合作,确保业务需求的正确表达。通用语言贯穿于整个设计过程,基于通用语言可以开发出可读性更好的代码,能准确的把业务需求转化为代码。

界限上下文则是用来封装通用语言和领域对象,提供上下文环境,保证在上下文内的业务概念和流程等有一个确切的含义,没有二义性。

业务概念往往由领域专家带领团队统一通用语言,明确上下文边界,以结算单这个概念在订单上下文和结算上下文的差异来举例:

订单上下文:记录一笔订单所购买商品的消费明细,包括商品原始金额、各项优惠金额、实付货币金额及种类。结算上下文:记录的是商家、平台、供货方在一段时间之内的应收应付款项。

明确上下文边界后,我们跟不同岗位的人沟通即使使用相同词汇也能准确理解其含义。

领域专家和领域知识

领域驱动设计强调由领域专家带领大家进行领域建模。领域专家指的是对一个领域的概念和业务流程精通的人,能快速识别或预判业务风险并能给出有效解决方案的人。 他可以是各个岗位的人,包括一个开发也能成为领域专家。领域知识则是这个领域的各种概念和业务流程。

战略设计与战术设计

领域驱动设计作为一种设计方法论,从两个方向指导设计思想,提出了战略设计和战术设计的概念。

战略设计是从业务视角出发,建立业务领域模型,划分领域边界,建立通用语言下的限界上下文。它是从顶层视角来审视我们的软件系统各个子模块之间的边界。

拿上面的流程举例来说明,一个有经验的领域专家会带领大家通过事件风暴建模的方法进行子域拆分,大致分为交易域、营销域、支付域、商品域、履约域。

战术设计则是从技术视角出发,侧重于领域模型的技术实现,完成软件开发和落地,它主要关注的是技术层面的实施。战术设计识别出来的是聚合根、实体、值对象、领域服务、应用服务和资源库等代码逻辑的设计和实现。


缓冲区

关于领域驱动设计的核心概念已经介绍了一部分,后面还有一部分。关于这些概念的涵盖范围见下图。

该内容为作者(知一)原创,首发在个人博客 https://noogel.xyz 和微信公众号『知一杂谈』,欢迎 关注、点赞、留言~


什么是领域模型

我们都不喜欢写 CRUD 的代码,只因为这些代码往往逻辑很简单,也不具备足够的扩展性,单一场景下可以很快开发出来,如果再加一个场景就又要开发一套,如果场景复杂并且不断变化,开发效率不仅会变慢,而且会更难以维护。下面通过支付系统来举例。

对于 CRUD 的实践来说,在对接支付渠道的时候,给每一家渠道都增加渠道单记录表,字段参照渠道参数定义的,对接微信时增加 wechat_trade 表,增加支付宝时增加 alipay_trade 表。问题就是当渠道增多时每次都建表显然不现实。

正常的做法则是,统一支付单记录,提取支付关键信息,通过总表和渠道表来记录,总表记录关键信息,把次要信息放入渠道表。相当于把支付单信息做了一次垂直拆分。

随着发展,新增了连续订阅业务,产品说需要在支付单中识别出是系统扣费还是用户主动付费的,这时你会想着扩列来支持,可是业务千变万化,不能每次都这样做。

其实软件开发中的许多问题,例如沟通问题、演化问题都和领域模型有关。领域模型是对领域内的概念类或现实世界中对象的可视化表示。它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。

实体和值对象

实体和值对象是组成领域模型的基础单元。

实体拥有唯一标识符,且标识符在历经各种状态变更后仍能保持一致。 对实体而言,重要的不是其属性,而是其延续性和标识,对象的延续性和标识会跨越甚至超出软件的生命周期。我们把这样的对象称为实体。从上面的实例来说,支付单有唯一的 ID,渠道单有自己的唯一 ID,它们都是实体。

当一个对象用来描述一个实物,而没有唯一的标识符,叫做值对象。 值对象本质就是一个集合,可以保证属性归类的清晰和概念的完整性。由于金额不能单独表达用户的消费额,需要由支付金额和货币类型组合才能表达,消费额是一组值对象。

聚合与聚合根

聚合是领域模型的具体表达。

聚合是业务和逻辑紧密关联的实体和值对象组合而成,聚合是数据修改和持久化的基本单元,一个聚合对应一个数据的持久化。 聚合在 DDD 分层架构中属于领域层,一个聚合提供一个业务核心能力,领域层包含了多个聚合,聚合内的实体以充血模型实现个体业务能力,以及业务逻辑的高内聚。

聚合根也叫做根实体,它不仅仅是实体,还是实体的管理者。 聚合之间通过聚合根关联引用,如果需要访问其他聚合的实体,先访问聚合根,再导航到聚合内部的实体。即外部对象不能直接访问聚合内的实体。

拿上面支付的例子来说,支付是一个聚合,支付单是聚合根,渠道单是依附于聚合根的另一个实体,渠道单的所有行为都要通过支付单进行 *** 作。

上面说到聚合之间通过聚合根关联引用,一个实体是否属于聚合根取决于所处的聚合。在退款聚合中,退款单是聚合根,绑定的支付单,在这里支付单是普通实体。所以是否是聚合根取决于具体场景。

聚合的特点:高内聚、低耦合,它是领域模型中最底层的边界,可以作为拆分微服务的最小单位。

欢迎一键三连~~

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5708877.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存