View on GitHub

软件开发与教练

blog

来源: http://codurance.com/2015/05/12/does-tdd-lead-to-good-design/ 作者:SANDRO MANCUSO

最近我发了一则推特,“TDD 无法带来好设计,如果你不知道好设计长什么样子”,并且说我们可能应该先教授设计再教TDD,(或者至少同时教授)。因为这条推特我和J.B. Rainsberger, Ron Jeffries,以及其他一些人进行了一场讨论。最终J.B和我在Hangout on Air进行了一场现场辩论。 如果你回顾我的讲演,blog,包括我的书,你都会发现我多次提到TDD是一种设计工具。那么为什么我现在不再这么主张了呢?

为什么我改变了想法

在仔细观察了我是如何工作的,以及很多其他开发人员如何工作后,我意识到没几个人通过TDD驱动获得了好的设计。尽管我深爱“红灯——绿灯——重构”的节奏,但单单一个“重构”的步骤并不足以使TDD被称为一个设计工具。 TDD并没有开出药方来告诉你应该怎么设计。它只是不停地缠着你,追问你:

“你确定写成这样么?是否已经足够好了?你能让它更加完善么?”

这种纠缠或者说是让你保持专注设计和代码改进的提醒,非常的棒,但是还不够。 在我看来,TDD是一种软件开发的流程,它带来了很多的益处,其中包括持续不断的提醒我们改进代码。 然而,改进代码到底要改成什么样,TDD却并未涉及。

难道你忘了简单设计四规则

嗯,是,也不是。我没有忘记。但是简单设计四规则不是TDD的一部分,而现在我在讨论TDD本身。很多经验丰富的TDD践行者通常都把简单设计四规则作为重构阶段设计的指导思想,包括我自己也使用它,以及其它技巧。 简单设计四规则是众多可选的设计思想之一。SOLID是另一选项,领域驱动设计是又一个,另有许多其他的设计原则和模式可以作为很好的设计指导。这些思想正是我们需要装在脑子里来进行重构阶段的。从另一个角度来看,对现有设计思想的透彻理解也会带给我们更好的设计。 TDD是一种流程(而非设计工具),在这个流程中的重构阶段,你可以发挥你已经掌握的的软件设计知识和技巧去帮助自己改进设计。

TDD并非只有一种

TDD有两种主要的风格,它们在何时进行设计有着相当显著的区别。

古典派

古典派是由Kent Beck开创的原本风格,也被称为底特律式TDD

主要特点
问题

由外而内


由外而内TDD,也被称作伦敦派或者mock式,是由一些XP实践先驱接受和发展出的风格。随后它启发产生了BDD。

主要特点
问题

我们应该用那种TDD风格

两种都应该用,不同的风格只是工具而已,应该根据实际需要来采用。经验丰富的TDD实践者会从一种风格换到另一种,根本不操心自己在用那种风格。

宏设计和微设计

有两种设计:宏设计和微设计。当我们用测试驱动代码时我们在进行微设计,主要用于经典式TDD。宏设计超出了我们正在实现的功能。它是关于我们如何在更高层面对领域进行建模,如何划分应用,层次,服务等等。宏设计给我们应用的整体结构,并让不同的团队和开发者可以齐头并进而不会相互阻碍。宏设计关系到商业层面如何看待应用,常常适用领域驱动设计之类的技术。宏设计也帮助保持应用的整体一致性。TDD并不能帮助我们在这个层面进行设计。 当采用由外而内方式TDD时,我们常常会考虑到宏设计,但是由外而内方式本身并不足以定义整个应用的宏设计。

结论

多年以来,我看到了很多由测试驱动开发的应用最终仍然很难维护。当然,我得说比起我以前维护的那些根本没有测试的遗留程序,它们要好得多了。 写或不写测试,程序员都可以搞出一团糟来。用经典式或由外而内式,程序员一样都可以驱动出一坨x。 TDD不是设计工具。它是一种软件开发的工作流程,在流程的整个周期里贯彻着对代码改进的提示。当面临这些提示时(写测试和重构),程序员需要了解一些设计方面的指导方针才能改善代码,如:

仅仅说“重构”并不足以把TDD称为一个设计工具。 很多程序员抱怨TDD和mock让它们写代码更慢了。最终他们都放弃了TDD因为太难得到他们想要的结果。在我看来,没有哪个程序员会对理解红灯——绿灯——重构的循环有什么困难。他们苦苦挣扎的事情,是如何设计良好的软件。 TDD最棒的一点就是它会持续不断的问我们

“嘿,你能把代码改得更好一点么?你看到这个类有多难测试了么?好了,现在这段代码工作了,绿灯。现在改进吧。”

但是除了这些,你还是得靠自己来写出更好的代码。 如果你理解了好的设计是长什么样子的,TDD做起来会容易很多。练习并理解现有的丰富设计原则会让TDD容易也有用很多。并且会让TDD的学习曲线平缓下来,也更容易被人接受。 偏激是不好的。我们一下从过重的前期设计(BDUF)变成完全没有设计。抛弃我们已有的设计知识是个错误。当然我们不应该回到过度设计每件事的黑暗时代,然而那种认为我们只需要关注微设计的想法也是错的。如果你是一个人搞搞,做些kata练习,或者开发一个小程序,那么随便你喜欢怎么样开发都可以。但是如果你是团队的一部分,开发一个比练习题大很多的软件,那么还是对你的团队行行好,多关心关心宏设计以及代码结构吧。

关于作者

Sandro Mancuso 软件工匠,作者,伦敦软件匠艺社区(LSCC)的发起人。尽管Sandro从1996年才开始职业生涯,他很早就开始编写代码了。他曾经在创业公司,软件工作室,产品公司,跨国咨询公司以及投行工作过。 在他的职业生涯中Sandro有机会接触各种不同的项目,语言,技术以及行业。他对于在各种规模的组织中推广软件工匠思想以及极限编程有着丰富的经验。Sandro由于发展和推广软件匠艺精神而享有盛名,并经常应邀在世界各地进行讲演。他的职业抱负是通过帮助程序员自我改善并更关注自己的手艺,来让整个软件行业更上一层楼。