聊聊领域驱动设计

Posted 微观技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊领域驱动设计相关的知识,希望对你有一定的参考价值。


更多精彩内容,欢迎关注:

https://github.com/aalansehaiyang/technology-talk  


汇总java生态圈常用技术框架、开源中间件,系统架构、数据库、大公司架构案例、 常用三方类库、项目管理、线上问题排查、个人成长、思考等知识


前言

DDD全写 domain driver design ,也称为领域驱动设计。大型复杂业务系统架构一般都会用到,在提高系统扩展性有很大帮助。

听着是不是很牛掰,感觉又有点虚,具体要怎么操作?有没有什么经验准则可以照着模仿?或者我是一个新手,要怎样快速入门?

概念

领域:本质上可以理解为就是一个问题域,比如社区的核心是会员、发贴、回贴。电商的核心是会员、店铺、商品、库存、交易、营销。只要确定了业务领域,那么系统要解决的关键问题、问题的范围边界基本就确定了。当然随着你在一个领域摸爬滚打时间越长,在这个领域中积累的技术经验会越来越丰富。

设计:主要指领域模型的设计,领域模型是整个系统的核心。每一个领域,都有一个对应的领域模型,领域模型能够很好的帮我们解决复杂的业务问题


驱动:是以领域为边界,分析领域中的核心问题(核心关注点),然后设计对应的领域模型,再通过领域模型驱动代码实现。所以说,当我们要开发一个系统时,应该尽量先把领域模型理清楚,然后再开始动手编码,这样的系统后期才会更好维护。


划重点:

通过设计领域模型来解决领域中的核心问题,模型驱动的思想。而不是面向过程的思想,走一步看一步。设计领域模型时,要考虑该领域模型是否满足业务规则,同时还要综合考虑技术实现等问题,比如并发问题;领域模型不是概念模型,领域模型关心技术实现,所以领域模型才能直接指导编码实现;关注核心问题,抓重点,而不是整个领域中的所有问题设计时应考虑一定的抽象性、通用性,以及复用价值;模型持续重构、完善、优化;

设计思路

1、理解领域

明确要设计一个什么样的系统,要解决什么核心问题。然后将问题拆分、需求细化。细化过程中可能会发现很多模糊的地方,需要拉上需求方进一步沟通,有时需求方也不是很清楚,此时如果有一个领域专家(对领域内的各种业务场景、业务规则非常清楚)特别关键。


2、拆分领域

如果一个领域的业务规则、交互流程、存储内容太多,导致我们无法直接针对这个大的领域进行领域建模。则需要拆分,把一个大的领域拆分成多个小的领域(子域),然后理清每个子域的边界;然后再搞清楚哪些子域是核心子域,哪些是非核心子域,哪些是公共支撑子域,还要思考子域之间的联系是什么。


划分子域的标准:按业务功能进行划分。比如会员:注册、登录、用户信息管理、业务权限打标;商品:商品信息录入、商品详情页、商品管理;交易:订单的生成、管理。


3、细化子域

细化每个子域,进一步明确每个子域的核心关注点:

• 梳理出领域内我们关注的概念、概念的关系,并统一交流词汇,形成统一语言;• 梳理出领域内我们关注的各种业务规则,DDD中叫不变性(invariants),比如唯一性规则,余额不能小于零等;• 梳理出领域内的核心业务场景,比如电商平台中的加入购物车、提交订单、付款等• 梳理出领域内的关键业务流程,比如下单会经过哪些详细流程步骤,先不着急考虑流程引擎、设计模式,先用伪代码把过程列出来,再考虑多种下单场景如何合并、抽取、优化。

4、领域模型设计

DDD提供很多实用的建模工具:聚合、实体、值对象、工厂、仓储、领域服务、领域事件。我们可以使用这些工具,来设计每一个子域的领域模型,最后产出领域模型图。下图是电商系统的商品中心的领域模型图:

5、技术要素

框架选型、架构设计、容量规划、数据库设计、分库分表方案、缓存设计、高并发解决方案、监控报警等


架构设计

  • 微服务

    •  强模块化边界。早期我们采用二方类库、组件的方式做模块化,可以做到工程上的重用;现在用服务的方式来做模块化,每个团队独立维护服务,有明显边界。

  • • 可独立部署,集群化对外提供服务,水平无限扩容

    • 社区开源框架活跃,象dubbo、spring cloud、motan

     •   微服务逻辑分层

     •微服务基础服务层。主要是基础性的支撑服务,如订单服务、会员服务、商品服务。向下承载存储,向上提供业务能力。     •   微服务聚合服务层。如果一个页面(APP、H5、PC)依赖于3个微服务接 口的数据,最好聚合封装到一个API内, 统一对外,而不是由client端发起三次API请求,减少客户端与服务端之间的连接开销。

              由于端上展示的信息粒度也不一样,PC 可能会展示的更多,而 App 则需要对信息作出一些裁剪。将适配、裁剪工作交由上层接口来做,底层基础服务更多负责业务通用性抽象。


  •  分布式事务。解决拆分微服务后,由于存储分散带来的事务问题。

      •  XA两阶段。第一阶段表决,第二阶段执行。缺点:锁定资源时间较长,性能影响大     •  TCC。Try、Confirm、Cancel。金融、电商应用较多。缺点:对代码侵入性强,实现难度大

               •  Try 阶段:Try 只是一个初步的操作,主要职责是完成所有业务的检查,预留业务资源。               •Confirm 阶段:确认操作,必须幂等,如果执行失败,事务协调器触发会不断执行,直到成功。               •Cancel:释放掉Try 阶段预留的资源,必须幂等,不断执行直到成功

   •   基于消息的最终一致性。依赖于下游业务的重试、补偿机制达到最终一致性。


   •   RocketMQ 消息事务。交互流程如图:

 •  熔断、限流、隔离、降级


以上是关于聊聊领域驱动设计的主要内容,如果未能解决你的问题,请参考以下文章

DDD领域驱动设计-DDD概览

构建领域驱动设计知识体系

2019领域驱动设计峰会领域场景驱动设计实战工作坊

领域驱动设计(DDD)实践之路(第二篇)

领域驱动设计

领域驱动设计认识了解什么是领域驱动