一个非教条式的TDD例子

本文为博客 VIP 文章,开通 VIP 后可阅读全文

开通 VIP

问题背景

数据分批器这个名字是我临时起的一个名字,源于我辅导的客户团队开发人员在当时的核心系统中要解决的一个实际业务问题 —— 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

相关推荐

我是如何成为一名全栈工程师的?

这篇文章讨论了全栈开发的好处和如何开始转型,以及在需求分析和架构设计中如何分层和隔离业务变化。作者分享了不同类型知识的学习方法和针对语言和框架的练习建议,以及通过结对编程和TDD加速学习的技巧。

IDEAL Garden 1005

如何利用链路追踪快速定位问题

随着微服务应用数量的增加,服务与服务之间的调用关系变得复杂,导致系统问题定位困难。链路追踪可通过唯一ID标记请求的整个调用链路,记录每个节点,快速定位问题。

IDEAL Garden 418

咨询师需要具备同理心

合作的建立在于双方有共识和目标,共识不断扩大,目标一步步达成,双方产生信任,但这个过程可能会充斥着冲突和争议,最有效的方法就是建立理解和联结,也就是同理心。

IDEAL Garden 391

DDD诊所——聚合过大综合症

“DDD诊所”是Thoughtworks DDD社区的一项活动,通过对同事们在实施DDD过程中遇到的问题进行分析和解答,共同提高开发水平。我们将其中一些典型案例整理成文供大家参考。之后也会考虑在适当的时候将这一形式对外部开放。

IDEAL Garden 342

如何编写技术文档?

所谓编写技术文档,基本意味着以结构化的方式组织文档,传达出清晰明确的信息,来让用户正确的使用你的软件产品。结构化文档不仅仅是当前最为主流的文档组织方式,在可预见的未来也会如此。

IDEAL Garden 596

你有“搜商”吗?

互联网信息检索是一个非常重要的能力。这里,我整理了一些常用的信息检索材料,希望能帮助到写作和需要在网络中获取数据的人们。

IDEAL Garden 413

如何建立你的离岸交付团队?

这里有四种离岸交付合作模式:Team Extension Model,Hybrid Collaboration Model,E2E Collaboration Model和Onshore/Offshore Collaboration Model。每种模式都有其优势和挑战,需要根据组织自身情况选择合适的模式。其中E2E Collaboration Model是一种全面的离岸交付模式,适用于团队成熟度较高、业务模块相对独立的情况。

IDEAL Garden 537

如何高效使用Gherkin

Gherkin语言有时候又被称为小黄瓜语言,它是第一种有着类似自然语言可读性的业务语言,用来描述业务行为,而不必关心具体的实现细节。它也是一种领域特定的语言,用来定义Cucumber格式的测试。

IDEAL Garden 593

低碳 Web 实践指南

本文探讨了如何构建低碳 Web 应用来应对气候变化和碳排放问题。文章指出,通过精简压缩 Web 应用、降低数据传输量以及优化应用性能等措施,可以减少碳排放。文章还强调了在软件开发生命周期中落地相关举措的重要性,并提供了一些测试工具和实践经验。

IDEAL Garden 466

简化Java单元测试数据

冗杂繁复的数据初始化代码会影响单元测试本身的代码质量,造成单元测试编写成本高、易读性差、易维护性低等问题。

IDEAL Garden 1459

什么是多运行时架构?

随着微服务架构在大规模组织中成熟落地,服务化体系规模的不断扩张也带来了一些典型问题:服务如何有效治理和接入?团队如何高效协作?本文介绍了多运行时架构解决上述问题的思路,并通过几种开源方案探讨了在实现中遇到的挑战,最后提出了对演进的设想及展望。本文介绍了多运行时架构的概念以及一些实现方案,并讨论了目前的实现中存在的限制与挑战,最后设想了一种未来可能的架构形态。

IDEAL Garden 1396

数据工程中的任务调度实践

数据工程的任务调度应该以“日志驱动”作为解决方案。而日志驱动的重要部分“日志解耦”正是提高系统健壮性的利器。

IDEAL Garden 319

如何避免AWS的高额账单?

尽管Serverless架构在某些方面表现出色,但在当前轰轰烈烈的“微服务”进程中,它仍然不是一种主要的选择。除了由于本身特性导致的使用场景受限外,我想乏善可陈的关于Serverless最佳实践的总结也是一个重要的因素。

IDEAL Garden 618

为什么企业要做大规模敏捷?

软件工程里一个重要的指标就是“可用的软件”,所以如何在提高代码质量,最大程度地减少软件中的Bug同时,平衡软件迭代速度与交付效率是我今天想跟大家讨论的问题。

IDEAL Garden 1061

数据离奇丢失案件的侦破与思考

数据出现问题相对比较严重,团队都会着急去排查原因,不过,在开始排查之前,有更重要的事情要做。我认为问题排查也分两个步骤:清晰识别问题、定位问题。

IDEAL Garden 769

结对编程的十个场景

本文以真实项目实践总结为基础,选取了结对编程中的典型场景,叙述了在敏捷交付项目中,开发者在实践结对编程时经常遇到的挑战。

IDEAL Garden 913

浅谈兼容性测试

兼容性测试是一种软件测试,用于确保构建的系统/应用程序/网站与其他各种对象(如其他网络浏览器、硬件平台、用户、操作系统等)的兼容性。这种类型的测试有助于了解产品在特定环境中的表现。

IDEAL Garden 630

从“高内聚,低耦合”说起

做设计时,优先以满足条件的模式为指导,当模式无法满足设计时,以对应层次的原则作为指导。当低层原则无法指导设计时,向高层依次寻找原则。当新的设计方案能解决某一类问题时,它可能就是一种新的模式。

IDEAL Garden 990

Mongo初遇回忆录

MongoDB 是一个操作简捷,面向文档存储的数据库。本文以一种独特的视角揭示了它的实践体验。

IDEAL Garden 731

探索云原生安全测试

由于不同时代所使用的架构和技术的差异,云时代面临着一系列安全测试挑战。然而,传统的安全测试手段和工具由于其固有的缺点,无法很好地适应云时代的安全测试需求。

IDEAL Garden 808

浅谈基于深度学习的漏洞检测

深度学习在图像处理、视频实体识别、自然语言处理等领域中已经取得了长足的发展和突出的成果,这自然驱使着安全研究员们将神经网络引入到安全领域中。

IDEAL Garden 1091

如何简单实现ELT?

ELT非常适合为数据湖仓或数据集市提供数据管道,并且可以用更低的成本,根据需求,随时对大量数据进行分析。本文主要介绍如何使用Airflow和dbt实现ELT流程,并与snowflake集成的方法。

IDEAL Garden 1040

Web性能评价指标

遇见用户抱怨性能时,不要先入为主地判定性能差,逐个排查系统可能有的性能问题,优化非最佳实践。而应该理性地以用户为中心,收集真实用户数据,衡量系统性能好坏。

IDEAL Garden 716

当谈论引用透明时,我们在说什么

谈论到引用透明(Referential Transparency),我们都会聊函数式编程(FP),会聊Effect和Side Effect,会聊纯函数(Pure Function)等,这些概念相互关联,有时甚至彼此引用定义,能够真正理解它们的含义非常重要。

IDEAL Garden 482

用技术应对气候危机

随着气候灾害,极端天气的频繁出现,关于气候变化的讨论已经越来越多。各国政府,各行各业也逐渐将可持续发展提上议程。软件作为日常工作生活中不可或缺的一部分,它和气候变化之间有什么关系呢?我们作为软件从业者,又可以做些什么来促进气候目标的达成呢?本文将从软件对可持续发展的影响出发,举例介绍软件如何从三个方面降低碳排放。然后就其中一个方向-软件自身碳排放进行介绍,再到绿色软件的定义,度量和原则。最后提出作为软件从业人员现在可以做些什么。那么到底什么是绿色软件呢?

IDEAL Garden 530

一次有效沟通的组成

一个合格的职场人,所需要具备最重要的三项技能:沟通能力,时间管理能力和团队合作能力,其中沟通能力又是作为基础当中的基础。

IDEAL Garden 526

AI测试的迷思

AI系统本身的发展还不足以很好地替代人在测试分析和测试设计方面的工作,导致AI实现的自动化测试的准确性以及可维护性比人工的方式更差,不过它的时间和成本优势却远远超过人工,这个也是其越来越火的根本原因。所以在测试领域,AI需要更加努力,才能真正替代人的工作。

IDEAL Garden 655

Tech Lead如何引导团队成员解决问题?

在团队成员向Tech Lead寻求帮助时,Tech Lead首先要做的是明确提示期望,识别能力差距,其次是引导团队成员自己得出解决方案,最后制定培训计划以提升团队能力。

IDEAL Garden 737

好代码的五个特质

如何衡量代码好坏?SOLID采用了一组原则来定义好的代码,但是原则更像是规则,要么符合,要么不符合。而软件开发过程非常复杂,其间充满了平衡和妥协,事实上并没有一种非黑即白的规则可以适用。

IDEAL Garden 519

我希望早点知道的关于成长的建议

这篇准备了很久,又临时起意,而终于“完成”了的短文,旨在将一些我觉得重要的建议讲给渴望成长,又不知从何做起的同学们。这里分享的几个小的点,做起来难度应该都不算大,如果能持之以恒,我相信你可以看到自己成长的速度。

IDEAL Garden 398
上一篇: 我是怎么读代码的
下一篇: 日志记录的最佳实践
Thoughtworks思特沃克中国
Thoughtworks思特沃克中国 企业官方账号 企业官方账号
博客等级 码龄25年 751粉丝 · 459原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值