使用测试驱动开发求解数独游戏

  • Kurt Christensen
  • 张海龙

2007 年 5 月 15 日

话题:敏捷文化 & 方法

去年,Ron Jeffries撰写一个系列关于测试驱动开发文章,通过尝试用 Ruby 编写一个数独游戏(Sudoku)解算器的方式,展示他如何实践测试驱动开发。Ravi Mohan最近找出这些文章,把它们与Peter Norvig的类似成果进行对比,指出了测试驱动模式作为设计方法的缺点。这一论据的核心在于,Norvig 博士提出了一种优雅的解决方案:

本文中,我处理了在解决每个数独迷题过程中遇到的问题。最后发现其解决方式还是非常简单的(只需要 100 行 Python 代码),它基于以下两个想法:约束传播查找

但是 Jeffries 的方法就繁琐多了:

我曾经设想过,或许可以先开始一个简单的数独游戏,然后试着用测试驱动开发来得出解决方案。但是我又觉得我没法那样做……所以,我打算以一套假定的内部数 据结构来构建游戏,然后并使用测试驱动开发来得到我认为应该会用得到的方法……会引起争议的是,这违反了 YAGNI 原则(You Aren't Gonna Need It),但由于我不知道如何开始,也不知道怎样才算完成,所以按 TDD 的方式先写一些零碎的代码对我来讲是一个合适的开始方式。

我不是在说这个好,也不是说你必须这么做,啥也不是。我只是在展示我在面对这些问题时是怎样做的,以及如何让我和我的电脑朝着数独游戏的解决方案这个方向前进。

换句话说,Norvig 的文章以一种将想法按逻辑递推的方式,来得到简洁优雅的解决方案(“推导求证(science as it's shown)”),相反,在 Jeffries 的一系列文章中给出的见解是通过实践探索得出的(“实践求证(science as it's done)”)。devgrind的众人对 Ron 的结果颇不感冒,他们对 TDD 做了如是评论:

“如果你手头只有锤子的话,那么所有的问题看起来就都像钉子。”而这也更加深了我对这些年来软件开发界的人士过多关注软件开发的方法论,从而低估了例如算法设计等基础方法重要性的看法。

Vladimir Levin就此为测试驱动开发展开了辩护,他指出创建算法和构建软件的区别:

想以测试驱动开发来构造算法的做法是愚蠢的,他只会使人们更容易误认为测试驱动开发不是一个有效的设计技术。那么测试驱动开发的目的是什么?它的目标是让人们慢慢变得不再去提前考虑那些将来才使用的类和方法。

换句话说就是,尽管 TDD 可能并不是构建新算法最好的工具,但它的优势在于如何应用这些算法去解决实际问题。另外一点:Peter Norvig 是 Google 的研发主管,是一本领先的人工智能教材的作者,也许是目前在世的最好的程序员之一。尽管我们当中很少有人会有那么大的激情去仿效他的思考方法,但了解自己在解决苦难问题时到底能走多远,还是有所帮助的。

查看英文原文:Solving Sudoku with TDD
译者简介:张海龙,现就职于Ethos,注重对项目管理的过程建立和优化、设计模式的理解和实践。与 InfoQ 中文站分享内容,请邮件至china-editorial@infoq.com
敏捷文化 & 方法