DDD的思路及基础知识

最近看了一篇文章,觉得很有意思,我把他分享出来 标题为:浅谈我对DDD领域驱动设计的理解,再说这之前,我们先梳理下什么是领域???


基本思路:

DDD(Domain-driven Design)又称领域驱动设计基本概念:
*领域,问题域,领域模型,设计,驱动
那这几个怎么融入到我们自己的项目里面呢?
*什么是领域?
*什么是设计?
*什么是驱动?
*什么驱动什么?


1.什么是领域(Domain)?

前面我们已经清楚的知道我们现在要做一个什么样的系统,这个系统需要解决什么问题。我认为任何一个系统都会属于某个特定的领域,比如论坛是一个领域,只要你想做一个论坛,那这个论坛的核心业务是确定的,比如都有用户发帖、回帖等核心基本功能。比如电商平台、普通电商系统,这种都属于网上电商领域,只要是这个领域的系统,那都有商品浏览、购物车、下单、减库存、付款交易等核心环节。所以,同一个领域的系统都具有相同的核心业务,因为他们要解决的问题的本质是类似的。

因此,我们可以推断出,一个领域本质上可以理解为就是一个问题域,只要是同一个领域,那问题域就相同。所以,只要我们确定了系统所属的领域,那这个系统的核心业务,即要解决的关键问题、问题的范围边界就基本确定了。通常我们说,要成为一个领域的专家,必须要在这个领域深入研究很多年才行。因为只有你研究了很多年,你才会遇到非常多的该领域的问题,同时你解决这个领域中的问题的经验也非常丰富。很多时候,领域专家比技术专家更加吃香,比如金融领域的专家。


2.什么是设计(Design)?
DDD 中的设计主要指领域模型的设计。为什么是领域模型的设计而不是架构的设计或者是他的什么设计呢?因为DDD是一种基于模型驱动开发的软件开发思想,强调领域模型是整个系统的核心,领域模型也是整个系统的核心所在。每个领域,都有一个对应的领域模型,领域模型能够很好的帮我们解决复杂的业务问题。

*什么是驱动?

—时间不够了改天再写
*
什么驱动什么?

—时间不够了改天再写

*拆分领域:
   就是把大的问题拆分成小的问题,逐个击破思路。然后既然把一个大的领域划分为多个小的领域(子域),
   那问题的关键就是把理清每个子域的边界,然后要搞清除那些子域是核心子域,那些是非核心子域,那些是公共支撑域,然后还要思考子域之间的联系是什么,
   那么我们该如何让划分子域? 我的个人看法是从业务相关性的角度去思考,也就是我们平时说的按业务功能为触发点进行划分。还是要拿经典的电商系统来分析。
   通常一个电商系统都会包含好几个大块
   会员中心:负责用户登录,用户信息管理
   商品中心:负责商品的展示,维护,导航
   订单中心:负责订单的生产和生命周期管理
   交易中心:负责交易相关的业务
   上面这些中心看起开很自然,因为大家对电子商务这个领域都已经非常的熟悉了,但是对待一个很冷门的行业,就不知道如何划分领域了,首先我们得努力理解领域内的知识。
   我个人从来不想去什么子领域的技巧什么的东西,因为我觉得这个工作没有任何诀窍可以使用。当我们不了解一个东西的时候,如何去拆解它?
   当我们对整个领域有一定的熟悉了,了解了领域内的相关业务的本质和关系,我们就自然而然的能划分出合理的子域了,
   不过并不是使用的系统都需要划分子域的,有些西戎只是解决一个小问题,这个问题不复杂,可能只有一两个核心概念。所以,这种系统完全不需要再划分子域。但不是绝对的,当一个领域,
   我们的关注点越来越多,每个关注点越来越多,我们会不由自主的取进一步的划分子域,也许我们一开始降商品和商品的库存都放在商品里,但是我们后来由于库存的维护越来越复杂,导致在一起
   对我们的维护带来一定的困难时,我们就会考虑将两者进行拆分,这个就是所谓的业务垂直分割
*细化子域
    我觉得我们细化的方面有以下几点:
        1.梳理领域概念:梳理出领域内我们关注的概念,概念的关系,并统一交流词汇,统一语言;
        2.梳理出领域内我们关注的各种业务规则,DDD中叫不变性(invariants),比如唯一性规则,余额不能小于0等;
        3.梳理业务场景:梳理出领域内的核心业务场景,比如电商平台中的加入购物车,提交订单,发起付款等核心业务场景;
        4.梳理业务流程:梳理出领域内关键业务流程,比如订单处理流程,退款流程等;
    从上面这4个方面,我们从领域概念,业务规则,交互场景,业务流程等维度梳理了我们导读要什么,整理了整个系统应该具备的功能。这个工作我觉得是一个非常具有创造性和难度的工作。
    关于领域概念的梳理,我觉得可以采用四色原型分析法,这个分析法通过系统的方法,将概念划分为不同的种类,为不同种类的概念标注不同的颜色。然后将这些概念有机的组合起来,从而让我们可以清晰的分析出概念和概念之间的关系。有兴趣的同学可以在网上搜索下四色原型。
    注意:上面我说的这四点,重点是梳理出我们要什么功能,而不是思考如何实现这些功能,如何实现是软件设计人员的职责。
*领域建模的方法
    1.划分好边界上下文,通常每个子域(sub domain)对应一个边界上下文(bounded context),同一个边界上下文中的概念是明确的,没有任何歧义;
    2.在每个边界上下文中设计领域模型,具体的领域型设计方法有很多种,如以厂家为触发点的四色原型分析法,或者我早起写的这篇文章;这个步骤最核心的就是找出集合根,并找出每个聚合根包含的信息;
    关于如何设计聚合,可以看一下我写的这篇文章;
    3.画出领域模型图,圈出每个模型中的聚合边界
    4.设计领域模型时,要考虑该领域模型是否满足业务规则,同时还要综合考虑技术实现,领域模型关心,所以领域模型才能直接指导编码实现
    5.思考领域模型是如何在业务场景中发挥作用,以及是如何参与到业务流程每个环节
    6.场景走查,确定领域模型是否能满足领域中的业务场景和业务流程
    7.模型持续重构,完善,精炼
*领域模型的核心作用:
    1.抽象了领域内的核心概念,并建立概念之间的关系
    2.领域模型承担了领域内的状态和维护
    3.领域模型维护了领域内数据之间的业务规则,数据一致性
*领域模型设计只是软件设计中的一小部分
    需要特别注意的是,领域模型设计只是整个软件设计中的很小一部分。除了领域模型设计之外,要落地一个系统,我们还有非常多的其他设计要做,比如:
   * 容量规划
   * 架构设计
   * 数据库设计
   * 缓存设计
   * 框架选型
   * 发布方案
   * 数据迁移、同步方案
   * 分库分表方案
   * 回滚方案
   * 高并发解决方案
   * 一致性选型
   * 性能压测方案
   * 监控报警方案
    等等。上面这些都需要我们平时的大量学习和积累。作为一个合格的开发人员或架构师,我觉得除了要会DDD领域驱动设计,还要会上面这么多的技术能力,确实是非常不容易的。所以,千万不要以为会DDD了就以为自己很牛逼,实际上你会的只是软件设计中的冰山一角而已。