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

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

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

  本文为【DDD】系列文章中的其中一篇,其他内容可参考:使用领域驱动设计思想实现业务系统

用一句话描述业务场景

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

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

小步快跑,不断迭代

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

短而高效的讨论很重要

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

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

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

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

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

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

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

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

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

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

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

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

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

用业务术语代替技术术语

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

上一篇:Java线程运行轨迹-代码追踪与定位


下一篇:D&F学数据结构系列——二叉排序树