本文结合团队在ECO(社区服务系统)业务建模过程中的实践经验,总结得到一些DDD业务建模的小招数,不一定是完美的,但是对我们团队来说很有效用,希望能帮到其他人。后面会陆续将项目中业务建模的一些经典例子放上来,分享给大家。

  ECO系统是线上旧系统,它的建模过程有别于新系统的业务建模。由于背着历史包袱,ECO的建模过程不是那么纯粹,很容易受到旧代码的影响,陷入代码的细节中,初期举步维艰,靠着小步快跑的方式得到了一些雏形和方法论,后面越来越顺,效果还是不错的。

  本文为【DDD】系列文章中的其中一篇,其他内容可参考:通过业务系统的重构实践DDD

用一句话描述业务场景

  这句话需要时一个完整的句子,有主谓宾状,可能还有定语。主语和宾语往往就是我们要找的实体/值对象,位于便是主语对应实体/值对象的行为方法,状语就是这个case下的业务规则,往往需要归类到前面的实体行为方法中,至于定语,也会是一些业务规则,同样要内聚到主语对应的实体中。

  举个例子,在社区发帖的业务场景下,我们尝试使用一句话描述:帖子作者只能在其已经加入了的某个圈子下才能发布帖子。对照上面的方法,那么“帖子作者”是主语,“帖子”是宾语,“发布”是谓语,“只能在其已经加入了的圈子下”是状语。这样我们可以得到“帖子作者”、“帖子”两个实体,得到“帖子作者”有一个“发布帖子”的行为方法,得到一条业务规则:帖子作者发布帖子的前提是加入对应的圈子。

小步快跑,不断迭代

  不要想着一口吃一个大胖子,有了模型的雏形就去实现它,在实现的过程中会发现更好的模型,再不断迭代完善,最后趋于完美。

短而高效的讨论很重要

  一定要有和别人讨论,尤其是和有建模经验的技术专家或者是业务专家进行讨论,有针对性的讨论,一次讨论的点不要太散,聚焦到一个需求模块,逐步挖掘业务模型。

  推崇的方式是会议形式的讨论,面对面的,毫无拘束的各抒己见。

  讨论时长不宜超过1小时,和其他会议一样,超过一小时效率大大降低,最后产出很低;讨论一定要聚焦,最好带着问题去讨论,比如让大家讲一下当前建模过程的困惑,对业务的理解。

  讨论过程中,如果遇到无法解决的疑惑或者无法达成一致的问题点时,不能耗费太多时间,可以记录下来,然后跳过,让大家回去想想,下次再重新讨论。

将你的建模思考过程写下来

  业务建模的过程是一个不断思考的问题,这个思考的过程我建议大家写下来,不管是将模型草图画在白板/纸上,还是通过一篇完整的blog表达出来,都是很好的。这个“写”的过程会让自己去梳理模型,去从各个case去观看模型,去审视模型的不足或者优劣,进而发现更合适的模型。

  我喜欢使用blog的形式,将每次建模过程记录下来,包括但不限于:业务建模、业务模型、代码示例。

  • 业务建模 —— 描述业务场景,建模的思考过程,最初的几次可能是不完整的,因为考虑的业务case是不全的,没有关系,只需要得出符合当前业务case需求的模型即可,后面的迭代中再去完善;我通常会尝试用一句话去描述这个业务case,从中发现业务模型。
  • 业务模型 —— 通过前面的业务建模思考,最终画出对应的业务模型草图,这里不要整个业务领域大而全的模型图,而是限定在你正在建模的这个模块或者是这个case下的模型,至于大而全的业务模型图,到模型相对成熟之后再做整合;只是在建模过程中不断和关联模型保持良好沟通即可,当然此类沟通能避免尽量避免,毕竟沟通信息越多,说明模块耦合越强,这可能是模块划分不合理的信号,需要警惕,当然这也不是绝对的,看情况而定。
  • 代码示例 —— 代码示例并不是要完成整个业务模型的实现,而是通过简单的代码将模型demo完成,而且最为重要的一定要通过写unit test 或者 写应用服务的形式来模拟模型的客户端调用,这样能发现很多模型的不足,尤其是发现模型中行为的划分和设计,更好地完善模型。同时有了代码demo,大家心里会更加有底气,有产出物也更早验证模型的合理性。但是要警惕千万不要陷入到代码的细节上,代码细节我们可以放到后续的编码过程中再去完善。

先从复杂的业务case开始建模

  业务建模先从复杂的业务case开始,直击业务领域要害,抓中核心,一网打尽。

  在一个聚合中个,我通常选择从”根实体”入手,在建模根实体的时候,会逐步涉及到其关联的其他实体/值对象,顺藤摸瓜似的完成了业务建模。

  另一方面,实践表明,业务模型中涉及case的复杂度从高到低依次为:"增" --> "改" --> “删” --> “查”,所以我的习惯是先将“增”这个业务case完成,基本上业务模型就八九不离十了,随后的三个case就变得简单了,当然其实“查”的case可能不止一个,但是大同小异。

  综合来看,聚合中的“根实体”相对其他关联实体/值对象,“增”相对与“改”“删”“查”都是较为复杂的业务case,复杂的搞定了,简单的自然而然就搞定了,所以建议从复杂的case开始建模。

切记使用技术术语,更多使用大家都懂的模型语言

  这一点在建模初期,大家容易走入误区,尤其是在有旧代码的老系统重构的过程中,大家通常会写入代码细节中,这时候建议撇开代码,单纯讨论业务模型。让每个人使用业务模型语言描述自己的问题和想法。这一点做起来蛮难的,但是需要坚持,到后面会发现大家不自觉就会使用模型语言来交流了。这个Evans在《领域驱动设计》一书中提及的“统一语言”相符的。

【DDD】领域驱动设计实践 —— 业务建模小招数的更多相关文章

  1. 【DDD】领域驱动设计实践 —— 业务建模战术

    本文结合团队在COMMUNITY(社区服务系统)业务建模过程中的实践经验,总结得到一些DDD业务建模的小招数,不一定是完美的,但是对我们团队来说很有效用,希望能帮到其他人.后面会陆续将项目中业务建模的 ...

  2. 【DDD】领域驱动设计实践 —— 业务建模实例(‘发布帖子’)

    本文是基于上一篇‘业务建模小招数’的实践,后面的多篇博文类似.本文主要讲解‘发表帖子’场景的业务建模,包括:业务建模.业务模型.示例代码:示例代码会使用java编写,文末附有github地址.相比于& ...

  3. DDD领域驱动设计和实践(转载)

    -->目录导航 一. DDD领域驱动设计介绍 1. 什么是领域驱动设计(DDD) 2. 领域驱动设计的特点 3. 如果不使用DDD? 4. 领域驱动设计的分层架构和构成要素 5. 事务脚本和领域 ...

  4. DDD 领域驱动设计-商品建模之路

    最近在做电商业务中,有关商品业务改版的一些东西,后端的架构设计采用现在很流行的微服务,有关微服务的简单概念: 微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成.系统中的各个微服务可被独 ...

  5. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(1)

    好久没写 DDD 领域驱动设计相关的文章了,嘎嘎!!! 这几天在开发一个新的项目,虽然不是基于领域驱动设计的,但我想把 DDD 架构设计的一些东西运用在上面,但发现了很多问题,这些在之前的短消息项目中 ...

  6. .NET应用架构设计—面向查询的领域驱动设计实践(调整传统三层架构,外加维护型的业务开关)

    阅读目录: 1.背景介绍 2.在业务层中加入核心领域模型(引入DomainModel,让逻辑.数据有家可归,变成一个完整的业务对象) 3.统一协调层Application Layer(加入协调层来转换 ...

  7. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(转)

    http://www.cnblogs.com/xishuai/p/ddd-repository-iunitofwork-and-idbcontext.html 好久没写 DDD 领域驱动设计相关的文章 ...

  8. 【DDD】领域驱动设计实践 —— UI层实现

    前面几篇blog主要介绍了DDD落地架构及业务建模战术,后续几篇blog会在此基础上,讲解具体的架构实现,通过完整代码demo的形式,更好地将DDD的落地方案呈现出来.本文是架构实现讲解的第一篇,主要 ...

  9. DDD 领域驱动设计-看我如何应对业务需求变化,领域模型调整?

    写在前面 上一篇:DDD 领域驱动设计-看我如何应对业务需求变化,愚蠢的应对? "愚蠢的应对",这个标题是我后来补充上的,博文中除了描述需求变化.愚蠢应对和一些思考,确实没有实质性 ...

随机推荐

  1. 49. leetcode 94. Binary Tree Inorder Traversal

    94. Binary Tree Inorder Traversal    二叉树的中序遍历 递归方法: 非递归:要借助栈,可以利用C++的stack

  2. Rabin-Karp【转载】

    问题描述: Rabin-Karp的预处理时间是O(m),匹配时间O( ( n - m + 1 ) m )既然与朴素算法的匹配时间一样,而且还多了一些预处理时间,那为什么我们还要学习这个算法呢?虽然Ra ...

  3. 安徽省2016“京胜杯”程序设计大赛_B_阵前第一功

    阵前第一功 Time Limit: 1000 MS Memory Limit: 65536 KB Total Submissions: 63 Accepted: 29 Description A国每个 ...

  4. Loadrunner分布式测试

    据经验,每生成一个虚拟用户,需要花费负载生成器大约 2M-3M 的内存空间.通常运行 controller的主机很少用作负载生成器.负载生成器的工作多由其他装有 LR Agent的PC 机来担任.如果 ...

  5. 【LeetCode】数组-1(643)-返回规定长度k的最大子数组的平均数

    好久没有刷LeetCode了,准备重拾并坚持下去,每天刷个两小时.今天算是开始的第一天,不过出师不利,在一道很简单的题目上墨迹半天.不过还好,现在踩过的坑,应该都不会白踩,这些可能都是以后程序员路上稳 ...

  6. 英文面试&笔试

    Topics:1.Talk about your carreer plan2.In ten years, what kind of people you will be? At that time,w ...

  7. 简单选择排序 Selection Sort 和树形选择排序 Tree Selection Sort

    选择排序 Selection Sort 选择排序的基本思想是:每一趟在剩余未排序的若干记录中选取关键字最小的(也可以是最大的,本文中均考虑排升序)记录作为有序序列中下一个记录. 如第i趟选择排序就是在 ...

  8. Git实用记录

    一.git命令名词解释 1.添加/跟踪/暂存:添加到本地索引 git add 文件名 2.提交:提交到本地仓库 git commit -m '注释' 3.推送:将提交到本地仓库的所有更新提交到服务器 ...

  9. 【Tomcat】重新獲得war包

    Extract war in tomcat/webapps #!/bin/bash #----------------------------------------------- # FileNam ...

  10. Win10家庭版设置桌面右键更换桌面壁纸

    Win10家庭版设置桌面右键更换桌面壁纸.. ------------------------- 这是设置之前的右键快捷菜单.. ------------------------- 开始设置:右键桌面 ...