《DDD with TLA+》(1) 建模思考
Domain Modeling from First Principle
领域建模的目的
First Principle 什么意思?
我们领域建模的目的是什么?我们是要解决什么问题。
我们不管采用什么方式,最终我们是为了解决问题,我们最核心的目标,通过我们构建一个系统,而我们的系统是满足我们的目标的。
所有这些方法,第一原则一定是解决问题。
What are they doing?
弄清楚业务到底干了什么(业务行为)
检查行为是否违反业务规则和约束
明确上下文,消除歧义
DDD 应该说做软件开始,这个概念就有。DDD 这个词是 2002 年出来的。最近几年热起来了。
在学 DDD 之前,你是怎么做的?
技术 VS 业务
如果我连解决的问题都不清楚的话,怎么做呢?其实不管你用不用 DDD 都会有这种思想。 所以这是个常识。
最大的区别是什么呢?
如果问题都不知道我们做什么东西呢?首先我们要知道我们做啥。否则怎么编程序呢。
否则技术再先进也没有用。
回归常识
我们这个课程的核心
思考的方法,如果能够清晰的表达我们要做什么。并在我们在实现之前,能够清晰的表达我所做的事情能否满足客户的要求。
其实这是最核心的东西。
例子:资源分配
需求
有一组有限的资源,供许多用户共享使用,需求如下:
1、如果用户当前没有持有任何资源并且没有尚未完成的请求,那么该用户可以发起一次资源请求(可以申请一组资源)
2、该服务一次可以分配一组可用资源给某个请求用户(一次分配不必满足用户请求的所有资源)
3、用户可以释放全部或者部分自己占用的资源
4、在获取到全部资源后,用户必须最终释放这些资源
思考
企业用的比较多,所以例子很多都是企业的例子。其实跟电信领域还是有差距。
按照你最自然的想法去思考就可以。你要把它做出来。
要 3 个资源,但我只有 2 个资源,也会分配。
建模的目的就是要表达我系统要干啥,这些都是我业务的目标。
这里面可能有些歧义的地方,大概的地方,我们第一步要准确的搞清楚我们要干什么。
从实现角度看和从外面看,------------这两个角度。
识别领域(图)
DDD 也是不断的演化。
(事件风暴)这里面都是什么人?什么角色?
这里更多的是领域专家。没有任何一个人对业务都清楚,所以要把他们都叫来。
在 DDD 刚开始,我们要领域建模,领域专家会解释要求,BA 分析好需求。
但是这个方式可能有点问题,“击鼓传花”似的传递错误。
What are they doing?
弄清楚业务到底干了什么?(业务行为)
这些人是在计算,每个人都说一下干什么,然后看一看在什么情况下发生,就像编程里的 if--else 一样,只不过这个层次更高。
发生什么事情
什么情况下发生
什么情况下某些事情一定不能发生
检查行为是否违反业务规则的约束
明确上下文,消除歧义
语言会有歧义,消除歧义就是 context
事件风暴
这个事情就叫事件风暴。
我们关注行为,干了哪些事情。
在企业应用里,这些东西是好找的,但是在电信领域里面可能不好找。但是电信领域里这些东西可能有人已经帮我们写好了。DDD 的发源是在企业应用里,我们不能照搬,但是我们可以借鉴它的思想。
Event Storming
Focus On Behavior Instead Of Data
Focus On Events Instead Of Nouns
Focus On Learning Instead Of Just Delivering
Donain Model
业务行为
l 不关注怎么做(技术无关)
l 着重描述什么发生了变化以及变化发生的条件
比如同一个订单不能 2 次支付
l 包容不确定性(各种实现方式)
业务约束和属性
行为过程中不能违反或者必须保持的业务规则要求
明确的语义
行为、状态、数据有无歧义的语义以及边界
Ubiquitous Language
只要做这件事情就是在做领域建模,只是如何去表达的问题。
这些问题都是高层次上的问题,这些问题如果没有识别出来,成本是非常高的。
领域语义层次的计算
提炼出和问题相关的领域变量(并不是把所有变量都提炼出来)
表达出领域变量的状态如何变化才能满足业务目标
变化发生的条件
变化要满足的属性
什么是一个分配
我不管怎么实现,我期望的结果是什么?
集合?
分类?
资源是什么我并不关心,完成一次分配是指:完成之前怎么样完成之后怎么样?
我们从外面看,一个分配需要展现什么样的结果呢?
其实就是两个集合的变化。
我要关心变化发生的条件。
行为:request allocate free
request request request allocate allocate request。。。。
各种情况都有
并发带来的问题
只把行为列出来是远远不够,只能通过测试。
测试出来了 BUG,改了之后也不知道是不是改好了。。。
Bound Context
没有这些名词的时候,不也照样开发系统么?不是说不知道这些名词了就不能开发系统。
就是把系统划开。语言要有语义,语义要没有歧义,要有 context。
对于我们电信系统如何划开呢?
我们在高层语义层次上表达清楚。
例子:电商
领域层次太高意义也不大。太低了也不行。
学习、演化
为什么 DDD 难学呢?是因为把 DDD 和面向对象的实践强行的绑在了一起,实体,值对象,聚合等概念。其实这些概念都不是 DDD 的本质。
但是 Bound Context 就没有好的实现方式。这就是为什么微服务一出来 DDD 终于找到了好的落地方式。
需要好的架构设计
微服务
Debuggable Design
把高层的设计出来之后,不用实现,就可以验证。这个设计可以 Debuggable,这也是这门课的重点内容。
评论