美文网首页是读书还是思考DDD知识汇金融基础技术与业务
致想给遗留系统写自动化单元测试的开发团队——事件风暴之父的工作坊

致想给遗留系统写自动化单元测试的开发团队——事件风暴之父的工作坊

作者: 程序员吾真本 | 来源:发表于2017-12-23 15:02 被阅读459次

    一家大型企业的关键业务代码已经年久失修成为了难以维护的遗留代码,有着硅谷高科技企业软件开发管理经验的高管决定在企业内部搞编写单元测试和重构的极限编程实践。这需要为企业遗留系统的代码编写自动化单元测试。那么编写自动化单元测试该从哪里入手呢?

    上文所提到的“领域驱动设计中国峰会2017”大会Event Storming 之父 Alberto Brandolini授课一天的“事件风暴工作坊”下午的“软件开发设计”(Software Design)环节,可以让开发团队了解系统应该具备的领域模型及其交互关系,为编写单元测试进而驱动重构提供指导。

    “领域驱动设计中国峰会2017”大会“事件风暴工作坊”下午的“软件开发设计”环节

    以下是实施步骤:

    1. 完成了“探索业务全景”环节。

    2. 确定要建模的需求
      在上午探索培训机构的业务的基础上,下午的任务是要为“替换Eventbrite在线应用“这个需求进行领域建模。假设你是Eventbrite的开发团队且想了解如果入手编写单元测试,那么可以把Eventbrite视作遗留系统,用以下步骤来为其建模。

    3. 了解领域模型之间的业务逻辑链
      从需求的起源来看,用户的需求来自于真实世界和 Read Model,并根据它们来进行 Decision Command(决策命令)。比如培训课程的听众根据“课程、价格、日期、讲师、城市、是否有空”这些 Read Model 来决定是否去报名参加培训。
      用户做了 Decision Command后,就会通过 Aggregate (像个状态机)或 External System (外部系统)来产生一个 Event(领域事件)。
      这些事件又可能会通过一个 Policy (业务规则)来触发下一个 Decision Command。


      用户做了 Decision Command后,就会通过 Aggregate 或 External System 来产生一个 Event,而这又可能会通过一个 Policy 来触发下一个 Decision Command
      我照着上图又画了一个版本
    三种事件风暴领域模型
    1. 用7种报事贴来贴领域模型并梳理业务逻辑链
      • Read model: 浅绿
      • User: 黄色小报事贴
      • Decision Command: 浅蓝
      • Aggregate: 黄色大报事贴
      • Event: 橙色
      • External System: 浅粉
      • Policy: 紫色
        按照从左到右的时间顺序来贴:


        用7种报事贴来贴领域模型并梳理业务逻辑链

    下面其中一组同学贴出的培训课程报名订票的业务逻辑链(报名者根据培训日期订票,通过一个未起名的 Aggregate 生成了 Ticket Booked 事件,这个事件又经由 Purchase Policy 触发了 Reserve Payment 的命令):


    培训课程报名订票

    事件风暴之父的忠告

    • 领域建模达成一致是很困难的,要有充分的心理准备。

    • 要邀请领域专家和团队所有成员,贴报事贴的空间要足够大。


      贴报事贴的空间要足够大
    • 在团队贴报事贴时,要观察不同业务部门的人的活动范围(比如财务人员不会跑到左边“培训课程准备子域”来贴报事贴,这很正常),这能启发你识别核心业务子域。有些核心业务子域是长长的一条,像泳道。有些则集中在一处,有些则会出现在一头一尾,这也很正常。


      有些核心业务子域是长长的一条,像泳道。有些则集中在一处,有些则会出现在一头一尾,这也很正常
    • 事件风暴领域模型聚集的方式有点像楼房——一片一片地出现。


      一片一片地出现
    • 开发团队不要盲目相信业务人员编写的用户故事,要合理地向业务人员 challenge 这些用户故事后面发生的事情。


      不要盲目相信业务人员编写的用户故事
    • 业务中的分支和开关会让你备受折磨,你需要衡量它们的全局价值成效来做取舍。


      需要衡量业务分支的全局价值成效来做取舍
    • Aggregate 和 Policy 的名字很难起,可以以后再起名。

    • Policy 是一种响应式的业务逻辑,它一旦接收到 Event,就会触发一个 Decision Command。

    • 有时候 Event 会通过"人工"的 Policy 来触发一个 Decision Command,但有时事实并不是这样的……


      有时事实并不是这样的……
    • 要识别那些“千夫所指”的业务瓶颈,首先消除这些最大的障碍,才能有效提升全局优化的成效。


      首先消除这些最大的障碍,才能有效提升全局优化的成效

    我的一些理解及 Brandolini 的回复

    • Aggregate 可以理解为“数据完整性的维护者”。
    • “千夫所指”的业务瓶颈可以作为编写自动化测试的第一个测试用例。
    • 我试图把 Brandolini 的上述7种事件风暴领域模型与 Evans 的 Model-driven design 中谈到的7种领域模型按下面的方式对应起来,但Brandolini给了令我惊叹的回复:
      • 我试图两者对应起来:
        • Read model(浅绿)可以对应 Entities 和 Value Objects,而后两者可以用 Factory 来创建,其中 Entities 可以保存在 Repositories 里面。
        • User(黄色小报事贴)没有对应。
        • Decision Command(浅蓝,可以对其编写自动化测试)可以对应 Aggregates、Entities 或 Value Objects 里面的行为。
        • Aggregate(黄色大报事贴,可以对其编写自动化测试)可以对应 Aggregates ,而 Aggregates 可以由 Factory 来创建,之后可以保存在 Repositories 里面。
        • Event(橙色)可以对应 Domain Events。
        • External System(浅粉,可以对其编写自动化契约测试)可以对应 Services。
        • Policy(紫色,可以对其编写自动化测试)可以对应 Aggregates、Entities 或 Value Objects 里面的行为。
          Evans 的 Model-driven design 中谈到的7种领域模型
          Brandolini 的7种事件风暴领域模型
      • Brandolini 的回复:
        • Eric Evans的领域模型出现在CQRS之前。虽然这些模型目前仍然有效,但是CQRS的影响力更大。
        • Read Model 如今是(DDD领域中的)一等公民。而将其对应到 Entities 和 Repositories 曾经是以前那些做法的薄弱环节。
        • Policies 其实是被漏掉了。Eric 从来没有说过领域模型的搜集工作已经完成了。所以对于这一点没有所谓的官方建议。一些人创建了代表进程的聚合,另外一些人则将大量的逻辑推向了 Application Services(这通常让领域模型变得贫血)。 Greg Young 曾指出在这些方面应该有所变化。
        • 我偏好于“对称性”的领域建模,即将 Aggregates 将 Commands 转化为 Events,而 Policies 对 Events 作出响应并调度 Commands 来进行工作。

    总结
    对于要为企业遗留系统的代码编写自动化单元测试的开发团队,可以在进行了“探索业务全景”环节之后,使用“软件开发技术”环节中的识别7种事件风暴领域模型的技术,来优先梳理那些“千夫所指”的有业务瓶颈的业务的逻辑链,然后可以开始对其中的 Decision Command、Aggregate 和 Policy 编写自动化单元测试。用这些单元测试来驱动遗留系统代码的重构,让遗留系统的代码变得易于维护。

    相关文章

      网友评论

      • 禚娴静:Policy可以举几个例子吗
        程序员吾真本:以一个互联网金融P2P平台进行交易系统改造中的客户还款场景为例。当一名借款人在该平台上成功借款后,例如借款金额为10万元,共有500人提供了借款,分为6期还款,每个月的最后一天为该借款的当月还款日。当一个月的月底到来时,这名借款人会到平台上进行还款操作,即保证自己账号中的金额大于当月所需还款金额+利息+平台管理费的总额之后,点击“还款”按钮进行真正的还款操作:1)当用户在平台上点击了“还款”按钮后,会生成一条还款启动的消息,发送到消息服务上。2)监听此消息的“还款开始”程序有一个policy,它一旦接收到此消息后,首先执行“找到未还款的计划”这个Command,并同时进行“写入还款请求” Command 和发送“还款计划计算消息”到消息服务上。3)“还款计算”程序的 policy 接收到还款计划计算消息后,进行还款总额的计算 Command,并同时进行占款 Command 和发起支付流程的消息到消息服务上。引自《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战》第6章。

      本文标题:致想给遗留系统写自动化单元测试的开发团队——事件风暴之父的工作坊

      本文链接:https://www.haomeiwen.com/subject/mrhqgxtx.html