谈谈DDD
从战略到战术,领域驱动设计(Domain Driven Design,DDD)给出了诸多关于软件架构、设计、建模与编码的方法和模式,以用于应对业务复杂度。然而,许多开发人员对于 DDD 的价值仍然心存疑惑,相反,对于它的难以理解、难以学习倒是确信不疑,甚至有人惊呼 DDD 是「反人类地难懂」。这真是现实给 DDD 沉痛的当头一击啊!
从 2004 年 Eric Evans 出版《领域驱动设计》一书以来,已有十五余载。实事求是说,DDD 的推进与项目落地真的是举步维艰。个中原因,难以说清。DDD 是否真正反人类地难懂可以另说,但它毫无疑问,是在反「早期的开发传统」。这一开发传统就是从实现技术出发,由数据驱动软件设计。软件开发人员往往擅长解决技术难题,却不善于(或者说不愿意)理清复杂的领域逻辑或对领域概念进行抽象。领域建模本身是一个主观思考的结果,这个问题也造成了优劣判定的不可衡量。
只要克服对 DDD 的畏难情绪(甚至是反感情绪),其实,DDD 的学习并没有想象中的那么困难。最大的挑战在于如何落地。当一个企业或者一个团队希望选择 DDD 帮助他们提升软件的设计与开发质量时,他们是否想过:
团队有没有专门的业务分析师,或者领域专家?
是否组建了特性团队,并以迭代的方式进行开发?
是否愿意以可视化的工作坊形式沟通需求,确定统一语言?
是否创造了足够的条件让特性团队的所有成员与角色能够面对面地高效沟通?
是否愿意为打造高质量的核心领域模型而为成本买单?
这些问题并非 DDD 能解决的,但却是成功实施 DDD 时需要确保的场外因素!因此,DDD 实施成败的关键,不仅在于 DDD 本身,还在于企业或团队能力成熟度是否达到了实施 DDD 的要求。这也正是为什么我要在《领域驱动设计实践》专栏中提出「领域驱动设计能力评估模型(DDD Capability Assesment Model,DCAM)」的原因所在。
我眼中的 DDD 已经超越了软件设计技术的范畴,它更像是一门哲学。何谓「哲学」,可以理解为是对人生、世界乃至宇宙的智慧思考。而 DDD 就是对软件世界的一种思考形式,它提出以抽象的领域模型去反映混乱的现实需求世界,以有序、合规、演进的方式去打造满足业务需求的软件世界,并尽量将技术因素推出这个世界的大气层边界之外。简言之,DDD 是我们观察软件世界的态度。
因此,对于学习 DDD 的开发人员而言,第一重要的不是掌握 DDD 的模式,而是要改变分析思维与设计思维的方式。将这种思维方式运用到软件项目开发过程中,就是我在专栏中提到的「领域模型驱动设计」,它的核心内容可以通过层层推进的形式汇集为如下三句话:
以领域为分析建模的驱动力
以场景为设计建模的驱动力
以任务为实现建模的驱动力
如何理解这三句话?
当你开始领域模型驱动设计时,必须在分析建模阶段抛开实现技术对你的影响,与需求分析人员、测试人员一起单纯针对「领域」进行分析建模,即提炼与抽象领域概念,并以统一语言和模型的形式来表达。
在设计建模阶段,围绕着一个完整的「场景」开展设计工作。需求分析人员为「场景」编写用户故事;测试人员为「场景」编写验收标准;开发人员则开始解剖「场景」,将其分解为组合任务与原子任务,然后各自分配给不同的角色构造型。
到了实现建模阶段,就针对这些任务定义测试用例,开始测试驱动开发,由内至外到达应用服务时,再将它们集成起来。显然,领域模型驱动设计就是针对领域开展的「合而分分而合」的解构过程。
同时,必须谨记:领域模型驱动设计的基础是限界上下文。在领域驱动设计的战略阶段,同样是一个「合而分分而合」的解构过程:将领域分解为限界上下文,再通过上下文映射联合限界上下文共同实现多个领域场景。
以上内容正是我言犹未尽想要表达的精髓。学习领域驱动设计,就需要抓住 DDD 的根本和精髓。你需要理解什么是限界上下文,它带来的价值是什么;你需要理解如何进行领域建模,统一语言在其中扮演了什么样的角色;你需要理解为何领域驱动设计提倡以领域为驱动力,为何需要领域专家参与到项目开发中来。
提升了对这些内容的认识后,再去学习 DDD 给出的设计模式,学习我在专栏中给出的固化设计过程,如场景驱动设计。然后找三两个不曾实施 DDD 的项目,寻两三个实施了 DDD 的项目,相互对比其模型与代码,你绝对会有一种醍醐灌顶的感觉。当然,这些都需要你沉下心来细心体会,认真思考,还需要你广泛涉猎更多软件设计与开发的知识,如此方能打通 DDD 的任督二脉。
至于团队实施 DDD,则不仅在于你个人的 DDD 知识与能力,而在于我前面提及的「场外因素」。企业或团队若期望在项目中实施 DDD,首先需要利用 DCAM 评估一下团队的能力成熟度,再来决策做不做 DDD,怎么做 DDD,并着手培养团队成员的 DDD 能力。《领域驱动设计实践》这个专栏可以在一定程度提高读者的 DDD 能力,却无法确保成功实施 DDD 的场外因素。
谈谈DDD的更多相关文章
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(3)
上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(2)> 这篇文章主要是对 DDD.Sample 框架增加 Transa ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(2)
上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(1)> 阅读目录: 抽离 IRepository 并改造 Reposi ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(1)
好久没写 DDD 领域驱动设计相关的文章了,嘎嘎!!! 这几天在开发一个新的项目,虽然不是基于领域驱动设计的,但我想把 DDD 架构设计的一些东西运用在上面,但发现了很多问题,这些在之前的短消息项目中 ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(转)
http://www.cnblogs.com/xishuai/p/ddd-repository-iunitofwork-and-idbcontext.html 好久没写 DDD 领域驱动设计相关的文章 ...
- DDD:谈谈数据模型、领域模型、视图模型和命令模型
背景 一个类型可以充当多个角色,这个角色可以是显式的(实现了某个接口或基类),也可以是隐式的(承担的具体职责和上下文决定),本文就讨论四个角色:数据模型.领域模型.视图模型和命令模型. 四个角色 数据 ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践
http://www.cnblogs.com/xishuai/p/ddd-repository-iunitofwork-and-idbcontext.html
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例
最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...
- DDD 领域驱动设计-在动手之前,先把你的脑袋清理干净
惨不忍睹的翻译 英文原文:http://www.codeproject.com/Articles/339725/Domain-Driven-Design-Clear-Your-Concepts-Bef ...
随机推荐
- Python套接字之UDP
目录 基于UDP的socket 发送消息 接收消息 基于UDP的socket 面向无连接的不可靠数据传输,可以没有服务器端,只不过没有服务器端,发送的数据会被直接丢弃,并不能到达服务器端 发送消息 在 ...
- I - Fill The Bag codeforces 1303D
题解:注意这里的数组a中的元素,全部都是2的整数幂.然后有二进制可以拼成任意数.只要一堆2的整数幂的和大于x,x也是2的整数幂,那么那一堆2的整数幂一定可以组成x. 思路:位运算,对每一位,如果该位置 ...
- 2019 kali安装pip/pip3
新版的kali中内置的python没有安装pip 0x01 pip(python2)安装: https://bootstrap.pypa.io/2.6/get-pip.py python2 get-p ...
- Upload-Labs 实验操作记录
0x01 安装 下载:https://github.com/c0ny1/upload-labs 环境:简单搭建phpstudy环境即可,记得在upload-labs根目录下创建该文件夹 0x02 文件 ...
- 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对
面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...
- LeetCode466. Count The Repetitions
题目链接 传送门 题意 定义一个特殊的串, 现在给出串S1和S2的参数, 问: S2最多可以多少个连接起来扔是S1的子序列, 求出这个最大值 解题思路 注意s1与S1的区别, 可以去看题目描述, 预处 ...
- 0day笔记(1)PE文件格式与虚拟文件内存的映射
PE文件格式 PE 文件格式把可执行文件分成若干个数据节(section),不同的资源被存放在不同的节中. 一个典型的 PE 文件中包含的节如下: .text 存放着二进制的机器代码 .data 初始 ...
- python学习笔记(四)---用户输入与while循环
用户输入 函数input demo1: message = input("all you input is chars:") print(message) demo2: 由inpu ...
- Mac安装Nginx、Mysql、PHP、Redis
安装xcode命令行工具的命令 xcode-select --install 安装homebrew: ruby -e "$(curl -fsSL https://raw.githubus ...
- 2019-2020-1 20199325《Linux内核原理与分析》第二周作业
冯诺依曼计算机硬件框图: 下面是一个简单的程序example.c. intadd_a_and_b(int a,int b){returna+b;}intmain(){returnadd_a_and_b ...