-- 知识铺
文章目录
- 一、领域驱动设计概念
- 二、领域建模方法论
- 三、领域事件
- 四、案例:敏捷项目管理系统
- 五、案例:电商场景领域模型设计
- 参考资料
一、领域驱动设计概念
1、基本概念
(1)通用语言
领域驱动设计,作为一个技术、产品、用户通用的语言进行沟通,极大地降低了沟通成本与沟通失真问题。
(2)领域设计4层模型
(3)DDD适合的场景
DDD既不是UI导向(SMART UI)、也不是数据导向(UML),而是以产品为导向,并不是用户所使用的产品,而是整个产品的业务逻辑。
适合中大型项目、API经济、中台化,可以借鉴DDD进行对微服务进行拆分。
2、领域、子域、界限上下文
领域(Domain):具备一个完整的,在一个市场里面赚钱的能力。比如说二手车市场、电商领域、宠物托管平台。
领域可以进一步划分为子领域。我们把划分出来的多个子领域称为子域,每个子域对应一个更小的问题域或更小的业务范围。
子域(SubDomain):比如支付子域、商品子域、用户认证子域。
界限上下文(Context):所谓上下文,就是为了解决子域的问题的。比如支付上下文,认证上下文。
子域提出问题空间,界限上下文提供解决空间。
3、核心子域、支撑子域、通用子域
核心域:核心域就是一个领域的核心。
比如说电商平台有哪些核心域:产品信息核心域、支付交易核心域、物流域,自然也就对应着产品信息上下文、支付上下文、物流上下文。
支撑子域:支撑核心域正常工作的子域。比如用户行为分析域、风控域,自然也有对应的界限上下文。
通用子域:一些业内通用的子域,比如用户认证系统,可以通过购买第三方的平台来实现。
4、界限上下文的关系
界限上下文的内容,就代表着对应的子域的功能。
界限上下文的上游(U-upstream)提供服务,下游(D-downstream)接收服务。
Conformist:跟随者关系。一定要跟某个上游系统绑定,但别人是主,本系统是从。
ACL(Anticorruption Layer):Open Host Service(RPC、消息队列等)/Published Language(xml、json等) ,反腐层。集成遗留系统,又不能强制老系统更新,新系统要做个适配器层来转换模型。
partnership:更紧密的合作伙伴关系。
Shared Kernel:共享内核。两服务之间紧密合作,代码模型可以提取成通用组件共享。
Separate Ways:分离模式。两个微服务没有任何联系。
Customer Supplier Teams(客户供应者模式):强依赖,上下游系统开发合作顺利,对模型逻辑修改反应迅速。常见于消息队列的两端。
Single Bounded Context(合并上下文模式):单个界限上下文,两服务如一家人,紧密到无法分开。一切模式要素都是共享的。
5、领域模型的要素 - 实体、值对象、聚合
(1)实体
(比如说一个学生)
唯一标识(用户提供、应用生成UUID/GUID、持久化生成)。
数据可变。
生命周期管理。(订单状态管理)
实体的唯一标识是实体与实体,聚合与聚合之间的纽带。
(2)值对象(Value Object)
(比如说一个学生中的某个属性,居住地、性别、性格等等)
无标识。(不唯一)
数据不可变,可复制,可替代。
整体性。(比如:¥100 - 两个概念一个整体,山东省济南市 - 两个概念一个整体)
通常用来做实体的度量和描述。
(3)聚合(Aggregate)
(比如一个班级,有学生、书)
事务一致性边界。(各种动作的数据一致性、行为一致性,比如说所有学生一起上课、下课)
聚合之间通过聚合根
(通常为聚合同名实体)进行沟通。
尽量缩小聚合(通常使用最终一致性和领域消息)。(缩小聚合事务复杂度就缩小了)
聚合是创建、发布领域事件和操作资源库的操作主体。
(4)案例分析
6、构建领域模型 - 工厂、库、领域服务
(1)工厂(Factory)
用于创建聚合和实体,可以用工厂类、工厂方法模式、创建者模式来实现。
实现了对象的解耦。
封装复杂操作过程。
(2)资源库(Repository)
实现对聚合的增删改查。
对接持久化机制(如Hibernate)。
和DAO、Mapper类似,但更侧重集合的处理。
封装复杂操作过程。
(3)领域服务(Domain Service)
无状态。
无法归为实体和值对象。
业务操作过程,对领域对象进行转换。
如:密码加密服务、文字转换服务、应收账款和应付账款对账。
7、反腐层
反腐层(Anti-corruption layer,简称 ACL)介于新应用和旧应用之间,用于确保新应用的设计不受老应用的限制。是一种在不同应用间转换的机制。
创建一个反腐层,以根据客户端自己的域模型为客户提供功能。该层通过其现有接口与另一个系统进行通信,几乎不需要对其进行任何修改。因此,反腐层隔离不仅是为了保护你的系统免受异常代码的侵害,还在于分离不同的域并确保它们在将来保持分离。
反腐层是将一个域映射到另一个域,这样使用第二个域的服务就不必被第一个域的概念“破坏”。
二、领域建模方法论
1、企业架构法
2、面向服务设计法(SOA)
3、用例分析法
4、四色建模法
红色:时标型(Moment-Interval)对象。
绿色:PPT(Party/Place/Thing)对象。
黄色:角色(Role)对象。
蓝色:描述(Description)对象。
5、初识Event Storming事件风暴
演进式架构和迭代式开发。
微服务拆分和向前兼容。
如何和产品业务人员沟通。
有没有一个可以在喝茶聊天中完成微服务拆分的方法?
6、领域模型的选择 - 贫血、充血模型
所谓的血,就是业务逻辑。
贫血:getter+setter方法,每个领域并没有太多业务逻辑,更多的业务逻辑在更上层。
充血:更符合领域驱动设计,应用逻辑为主、数据管理为辅。get、set方法是私有的,对外暴露的是更加丰富的有血有肉的方法动作。
贫血模型和充血模型各有优势:
贫血模型:上手快、发展受限,适合应用逻辑简单、信息记录类型的业务。
充血模型:上限高、适合三高项目,适合逻辑复杂、信息处理类型的业务。
7、洋葱圈模型
三、领域事件
1、初识领域事件Domain Event
异步通信,符合事件驱动风格。
通常用消息队列(MQ),可以实现削峰填谷。
但是要处理消息丢失、消息重复的问题。
2、领域事件,代码实例
(1)生产者发布事件
(2)消费者订阅事件
(3)EventStore做事件存储
(4)定时任务轮询投递事件
3、领域事件与CQRS
(1)什么是CQRS
CQRS:Command Query Responsibility Separation。(写和读的责任分离)
Command:执行动作,返回void。(行动可能会改变聚合、实体、值对象的内容)
Query:只查询,不修改对象状态。
适用CQRS的风格:事件驱动系统风格、管道过滤器风格。
(2)CQRS和ES事件溯源
普通CQRS:做数据的增删改查,对于数据无法溯源。
事件溯源:数据只做增和查,可以做到事件溯源。
四、案例:敏捷项目管理系统
1、功能分析
项目管理系统,涉及项目发布、代办、状态、任务等等。
2、子域划分
3、定义实体、值对象、聚合
(1)聚合根
领域驱动设计中,对外提供功能的只有聚合根的功能,聚合根里面的实体尽量只对聚合根提供服务。
聚合根的子对象,尽量都用实体对象封装。
(2)值对象
值对象不提供独有的ID,全部通过快速复制快速创建,永不修改来实现这些值对象的描述性的信息。
(3)实体
把子对象用实体的形式进行封装,成员变量private,set和get方法private,让它们更加生动的操作protected,让其他成员来访问。,聚合根里面的实体尽量只对聚合根提供服务。
(4)聚合
把聚合根、值对象、实体打包起来,就形成了聚合。
4、落地工厂、库、领域服务
(1)工厂
(2)资源库
(3)领域服务
5、落地反腐层
(1)完整图示
(2)领域服务
(3)适配器:进行适配+调用上有服务
6、应用服务
应用服务的方法与工厂、资源库之间的关联:
7、建模的核心要素 - 隐性的概念显性化
隐性的概念显性化:多种不同的逻辑封装到一起,按情况进行处理。
隐形的上下文显性化。
封装多对象行为。
8、规则选择 - 策略模式
9、规则拼装 - 组合模式
10、事件风暴 - Event Storming
(1)事件Event
事件即事实,即在业务领域中那些已经发生的事件就是事实,并可能需要保存下来或者让“别人”响应。
事件是对系统产生了业务上的影响的动作,相对的,如果仅仅是数据查询操作,则只会对系统产生技术上的影响,如CPU上升或者内存上升等。
注意:一般查询操作都不会触发事件的产生,所以查询操作不是事件,如点击了查询按钮显示了数据列表,一般情况下不会有类似于:数据已查询或列表已查询,这样的事件。
事件使用正方形橘黄色的便利贴表示,并且是过去式,如:用户已注册(User Registered),激活邮件已发送(ActivationEmail Sended)等。
(2)痛点/问题/关键点(IDEAS, RISKS)
关键点用红颜色的贴纸表示。
表示不确定的点、有风险的点或者需要特别注意的点,一般贴在事件旁边,代表这件事情值得特别关注。
(3)命令Command
决策命令产生了事件,可理解为产生事件的动作,与事件一一对应。如用户已注册(User Registered)事件对应的决策命令就是注册用户(Register User)。
决策命令用正方形蓝色便利贴表示,在实践中只需要将事件“反过来”就行了。
(4)聚合Aggregate
某个Actor在某个聚合调用某种Command产生了某个Event。
比如前面的用户已注册(User Registered)事件,是由普通用户(Normal User)在注册薄(Register)上调用注册用户(Register User)这个命令而产生。
聚合使用紫色即时贴表示。
(5)外部系统External System
Event不一定由前面所说的某个Actor触发Command而产生,也可能是由外部系统或者某种规则自动触发Command而产生。
外部系统使用绿色即时贴表示。
(6)第一阶段成果
(7)构建微服务间关联关系
(8)形成类图
(9)事件风暴核心思想
由下而上,更快:平时我们拆分都是从上层架构师进行总的模块拆分,再分到每一个模块里面。事件风暴从一个个事件开始,从下往上的考虑,出手更快。
事件驱动,更新:事件风暴是由事件驱动的,非常容易更新,当整个架构定下来以后,一旦用户体验有所变化,只需要改变对应的聚合。
团队破冰,更嗨:面前贴一张白纸,通过这种沟通,团队之间心平气和的把服务拆分的非常完美。
10、DDD模型下的代码分层模型
五、案例:电商场景领域模型设计
1、子域
核心子域:买家、支付、履约、卖家、市场、用户、风控、客服、搜索、财务、产品、定价、认证、内部、推荐、社交、合作、库存。
通用和支撑子域:数据平台、数据科学、负载管理、内容管理、消息通告、安全加固、基础架构、应用平台、质量保证、集成发布、遥测监控、合规审计。
2、上下文
认证上下文:注册认证、用户登录、访客登录、内部登录、身份验证、令牌管理。
用户上下文:用户联系、用户服务、用户设备、用户喜好、用户背调、用户支付、用户行为、用户设置、用户订单、用户发布、用户折扣、会籍管理。
市场上下文:折扣策略、优惠券、促销管理、用户粘性、SEO、SEM。
搜索上下文:公共搜索、个人搜索、信息编目。
客服上下文:语音客服、机器人、客户关系。
买家支付上下文:支付方式、支付网关、支付交易、保险。
卖家支付上下文:支付方式、支付网关、支付交易、税务。
履约上下文:卖家履约、买家验收、物流。
风控上下文:风控模型、支付风险、账户风险、交易风险。
推荐上下文:个性推荐、趋势推荐、广告推荐。
定价上下文:价格限制、价格推荐、费用计算。
买家上下文:下单、订单、购物车、跨境交易。
卖家上下文:发布管理、一手平台、二手平台、订单。
财务上下文:子账、收入、利润、税收、对账、应收应付。
参考资料
https://zhuanlan.zhihu.com/p/399103071
https://blog.csdn.net/wanghaiping1993/article/details/125493541
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/geek001/post/20240627/%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1DDD%E8%AF%A6%E8%A7%A3%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%8B%86%E5%88%86%E7%A5%9E%E5%99%A8_ddd%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1--%E7%9F%A5%E8%AF%86%E9%93%BA/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com