问题背景
数据分批器这个名字是我临时起的一个名字,源于我辅导的客户团队开发人员在当时的核心系统中要解决的一个实际业务问题 —— Oracle的数据库删除每次只支持1000条。这个问题更确切的讲是因为Oracle对下面这句SQL语句的支持约束:
代码语言:javascript复制delete from t_table where id in (ids)
问题就出在这个where id in ...上,后面传入的集合参数ids最大支持1000条。而实际业务场景中存在大于1000条数据,所以需要进行分批处理。
针对这个问题,我暂时不去探究这个SQL机制本身的合理性[1]。本文我想借这个机会聊聊如何运用TDD的方式去完成这个数据分批处理的设计和开发。
需求分解
基于这样的问题,我的习惯是先对问题进行分解,也就是TDD前要做的一个关键动作 —— Tasking。我快速做了个Tasking:
- 非1000的整数倍,小于1000条
- 1000的整数倍
- 非1000的整数倍,大于1000条
基于Tasking结果,对上述需求场景进行实例化,实例化过程中,边界值是我要考虑的重点:
- 非1000的整数倍,小于1000条
- 0条
- 369条
- 1000的整数倍
- 1000条
- 2000条
- 非1000的整数倍,大于1000条
- 1369条
- 2222条
原有设计
上述代码的for循环中做了两件事,边截取不同范围的recordsId,边调用了 CustomCustomerRiskScoreRepository 来做数据库操作,分批逻辑和存储夹杂在一起的过程式设计的好处是直接了当,当然也让 deleteByRecordIds() 的职责过多。
新的设计
基于我对软件设计浅薄的理解,我认为这个分批逻辑和Repository数据存储逻辑分开会更优雅,支持我的几个主要理由是:
- 数据存储逻辑更加纯粹,它只用关心数据的CRUD。
- 重要:分批逻辑可以很方便地进行自动化测试。
- 分批逻辑独立出来,方便复用和维护。
基于以上的几点理由,我在原来的过程式程序设计的基础上引入一些OO的理念,进行对象建模,比如抽象出一个数据分批器。我把对象建模过程看做在TDD之前的一些简单且必要的设计。