TDD与 数学形式主义:敌还是友?

反对TDD的经验过程,以及大量使用单元测试,反对使用基于数学的技术,以及使用“正式方法”和形式验证,这是很常见的。 但是,最近我再次体验到TDD的过程确实可以帮助发现并利用非常适合所考虑问题的数学形式主义。 然后,我们将从数学形式主义中受益,以实现更容易的实施和正确性。

在我们需要在软件中建模的业务概念中,数学结构,或更普遍地说是“既定的形式主义”,就像埃里克·埃文斯(Eric Evans)所说的那样,很常见。

日期以及我们如何自由使用它们进行金融工具交易提供了一个具有基本数学结构的业务概念的很好例子:期货交易者经常使用“ U8”这样的符号? 描述到期日期,例如2018年9月; “ U”表示9月,“ 8”表示? 数字表示2018,但也表示2028和2038等。请注意,该表示法仅可使用10年,并且每个代码每十年回收一次。

70年代初的IMM交易大厅(CME集团照片)

对于IMM合同代码,我们只关心以下方面的季度日期:

  • 三月(H)
  • 六月(M)
  • 九月(U)
  • 十二月(Z)

这样,该月只能产生4种可能性,再加上10种可能的年份数字,因此在10年的范围内总共有40种不同的代码。

如何将其转换为源代码?

作为软件开发人员,我们一直被要求管理此类IMM到期代码:

  • 排序一组给定的IMM合同代码
  • 在当前的“领先月份”合同中查找下一个合同
  • 列举当前《交货月份》合同中的下11个代码,等等。

这通常是临时完成的,每个用例都有成千上万个函数,导致数千行代码难以维护,因为它们涉及到对'U8?的解析。 每次我们要计算内容时都要格式化。

借助TDD,我们现在可以更加严格地解决该主题,首先要进行测试以定义我们想要实现的目标。

有趣的是,在进行TDD的过程中,IMM代码的循环逻辑使我震惊,并强烈地使我想起了Z / nZ循环组。 多年前,我在学校遇到一个奇怪的数学家,顺便说一句,我很难受。 但是现在在一个真实的例子中,它肯定会更有趣!

这篇文章的源代码(Java)在Github上

利用既定的形式主义

多亏了Google的帮助,即使对名字的模棱两可也很容易找到东西;多亏了Wikipedia,很容易找到关于诸如Cyclic Groups之类的任何已建立形式主义的更多信息。 我们特别发现:

“每个有限循环群与群{[0],[1],[2],…,[n? 1]}在加法下取n为模的整数”

Wikipedia页面还提到了与循环基序(此处为元素数)相关的乘积的概念。 看起来这是一种数学式的说法,即每个季度的4种可能性与10种可能的年份数字相结合,总共给出40种不同的代码。

所以呢? 听起来我们可以将一个周期组的四个月的集合标识为另一个,将十年数字的组标识为另一个,并且甚至两者的组合(乘积)也看起来像是一个10 * 4 = 40(即使加法运算不会这样调用)。 所以呢?

因为我们已经看到任何有限循环组和相同阶数的整数循环组之间都存在同构,所以我们可以切换到整数循环组逻辑(纯整数和模运算符)来简化实现时间。

基本上,想法是从IMM代码«Z3转换? 到0..39范围内的对应“普通”整数,然后对这个“普通”整数(而不是实际代码)执行所有操作。 然后,我们可以格式化回代码«Z3? 每当我们真正需要它时。

有了完整的正式解决方案后,我还需要TDD吗?

我必须坚持认为,我没有那么容易得出这个结论。 TDD的过程确实非常有用,可以避免一路走到每个可能的方向。 即使您找到了可以一次性解决问题的形式结构,甚至以“形式证明形式”,也可能需要较少的测试来验证正确性,但是您仍然需要进行测试以考虑规范问题的一部分。 谨在此提醒您,TDD与单元测试无关。

循环群中的偏序

给定IMM代码列表,我们经常需要对它们进行排序以进行显示。 问题是循环组没有总顺序,该顺序取决于您的时间。

让我们以也构成一个周期的星期几为例:星期一,星期二,星期三…周日,星期一等。

如果我们只关心未来,那么星期一是WEDNESDAY之前吗? 是的,除非我们在星期二。 如果我们在星期二,则“星期一”表示下一个“星期一”是在“星期三”之后,而不是在“星期三”之后。

这就是为什么我们不能不幸地仅仅实现Comparable来处理订单的原因。 因为我们需要考虑参考IMM代码的偏序,所以我们需要求助于Comparator,该Comparator在其构造函数中使用参考IMM代码。

一旦我们将这种情况识别为整数的循环组,就可以轻松地将比较的两个操作数都移位为0,然后再以安全的方式(总顺序)进行比较。 同样,TDD测试提供了自由的实验能力,使这一技巧成为可能。 只要我们还是绿色的,我们就可以尝试任何时髦的方法。

尝试作为kata

这个示例也是我们不久前在工作中尝试过的一个很好的编码方法。 给定IMM合同代码格式的简单表示,您可以选择对排序进行编码,查找下一个和上一个代码,甚至可以优化内存(例如,懒惰地缓存实例)和速度(缓存toString()值,例如在构造函数中),如果您还有时间的话。

在结束时

数学结构隐藏在许多常见的业务概念后面。 我养成了随时随地寻找它们的习惯,因为它们总是帮助我们思考,它们帮助质疑我们对领域问题的理解(«我的领域问题在某种程度上真的类似于该结构吗?»),当然因为它们经常提供出色的现成实现提示!

参考: TDD与。 数学形式主义:敌还是友? 从我们的JCG合作伙伴 Cyrille Martraire在Cyrille Martraire的博客博客中获得。

翻译自: https://www.javacodegeeks.com/2013/01/tdd-vs-math-formalism-friend-or-foe.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值