一个非教条式的TDD例子

本文通过一个实际的数据库分批处理问题,展示了如何运用领域驱动设计(DDD)和TDD(测试驱动开发)进行非教条式的设计和开发。作者首先对问题进行需求分解和设计,然后通过编写测试用例逐步实现功能,同时讨论了TDD中一些常见的教条,如提前设计和测试必须先失败,并提出了自己的见解。文章强调了显性化知识和夯实基本功的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题背景

数据分批器这个名字是我临时起的一个名字,源于我辅导的客户团队开发人员在当时的核心系统中要解决的一个实际业务问题 —— Oracle的数据库删除每次只支持1000条。这个问题更确切的讲是因为Oracle对下面这句SQL语句的支持约束:

delete from t_table where id in (ids)

问题就出在这个where id in …上,后面传入的集合参数ids最大支持1000条。而实际业务场景中存在大于1000条数据,所以需要进行分批处理。

针对这个问题,我暂时不去探究这个SQL机制本身的合理性[1]。本文我想借这个机会聊聊如何运用TDD的方式去完成这个数据分批处理的设计和开发。

需求分解

基于这样的问题,我的习惯是先对问题进行分解,也就是TDD前要做的一个关键动作 —— Tasking。我快速做了个Tasking:

  1. 非1000的整数倍,小于1000条
  2. 1000的整数倍
  3. 非1000的整数倍,大于1000条

基于Tasking结果,对上述需求场景进行实例化,实例化过程中,边界值是我要考虑的重点:

  1. 非1000的整数倍,小于1000条
  • 0条
  • 369条
  1. 1000的整数倍
  • 1000条
  • 2000条
  1. 非1000的整数倍,大于1000条
  • 1369条
  • 2222条

原有设计

上述代码的for循环中做了两件事,边截取不同范围的recordsId,边调用了 CustomCustomerRiskScoreRepository 来做数据库操作,分批逻辑和存储夹杂在一起的过程式设计的好处是直接了当,当然也让 deleteByRecordIds() 的职责过多。

新的设计

基于我对软件设计浅薄的理解,我认为这个分批逻辑和Repository数据存储逻辑分开会更优雅,支持我的几个主要理由是:

  1. 数据存储逻辑更加纯粹,它只用关心数据的CRUD。
  2. 重要:分批逻辑可以很方便地进行自动化测试。
  3. 分批逻辑独立出来,方便复用和维护。

基于以上的几点理由,我在原来的过程式程序设计的基础上引入一些OO的理念,进行对象建模,比如抽象出一个数据分批器。我把对象建模过程看做在TDD之前的一些简单且必要的设计。

💡 TDD不太提倡在开始前不做任何设计,恰恰它提倡做一些简单且必要的程序接口设计 —— 非教条主义

通过对象建模分析,我设计了两个简单的对象,一个是BatchDivider,另一个是Range,UML如下:

BatchDivider接收一个总数,然后能够返回一个包含了起止的范围的集合,比如接收1369条,返回集合[Range(0, 1000), (1000, 1369)],起止信息我用Range对象来表示。

前期的设计就做到这,我没有花太多时间去纠结细节,因为现在的设计足够让我起步了。如果在后续发现了不完善的地方,交给后续的驱动和重构。

编码落地

至此,我已经把需求进行了分解和实例化,然后也做了简单的程序设计,跑步前的热身完毕,接下来我就打算采用TDD的跑姿小跑起来。

之前的实例化我写得比较简单,由于我习惯用Given-When-Then的方式来描述,我把之前简单的实例化再结合当前的程序设计做了细化:

非1000的整数倍,小于1000条

  1. 0条
  • Given 待分批数据是0条
  • When 分批处理
  • Then 批次结果为空集合, []
  1. 369条
  • Given 待分批数据是369条
  • When 分批处理
  • Then 批次结果包含1个Range的集合,[(0, 369)]

1000的整数倍

  1. 1000条
  • Given 待分批数据是1000条
  • W
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值