问:开发人员面对面的交流过频繁,导致大会小会不断,如何把握这个度?

  答:面对面交流不是开会。只要觉得需要去交流。

  问:简单设计的粒度如何把握,如果强调前期架构的简单设计,如何应对软件投入运行后,短时间内,由于客户业务的扩张导致的数据容量的增大或者网络访问量的增加,而导致原有的设计已经不能满足用户的需求?

  答:请参见前面那个关于架构的回答。首先,你要有丰富的经验和知识,这些东西可以为你提供一个架构演化的方向。如果没有这些东西,基本上没有可能首次找到正确的方向。有了方向后,下面是TDD+Refactoring不断演化。

  问:简单设计如何能保证实施测试驱动开发?如果设计的不够详细,如何对接口编写测试用例和测试代码?

  答:首先,不是简单设计保证实施测试驱动开发,而是测试驱动开发可以促使你得到一个简单的设计。其次,是先有测试用例,然后才有设计和接口。

  问:《敏捷》书中把创建验收测试作为一种设计系统架构的重要手段,也作为对终用户的一种功能演示,但本质上还是对系统特性的一种模拟集成测试,并不能完全代表实际系统,这种验收测试与传统意义上的验收测试不同,这种验收测试可靠吗?

  答:这里所指得传统意义上的验收测试是什么?是指有测试人员进行的测试吗?一般在敏捷方法中(特别是XP)所指的验收测试,都是由QA和客户代表共同编写的,如果通过表明实现了客户需求。我觉得没有其他方法能比这个方法更可靠了。

  问:测试驱动开发的例子中,开始也做了简单的设计,然后再编写测试用例,后形成另外一种设计。开始时需要设计吗?如果需要,应该达到什么程度?开始不进行设计而纯粹依靠测试来驱动设计可能吗?我的理解是,测试驱动开发更适合于详细设计阶段,测试驱动开发适合于架构设计吗?文章中的测试驱动开发例子中,软件需求好像来自个人“随心所欲”的想象,这种测试用例的生成方法是否缺乏系统性和完备性?或者说,测试驱动开发的测试用例的产生是否也需要严密的设计呢?

  答:什么是设计?这是一个必须首先达成共识的问题。TDD的核心是持续设计,不断关注设计质量,这种关注是建立在频繁的、真实的反馈的基础之上的,而不是一些臆想。达到的程度是“tunedtotodayandpoisedtostrikeattomorrow.”通过一些想象画几张UML图,那不是设计,设计应该是可验证的,并且要通过反馈持续修正的。设计的验证正是通过测试用例进行的。测试用例可以是客户需求,这是验收测试。也可以是开发团队内部实现上的需求,这是开发团队内部的测试(一般也成为单元测试)。测试用例应该来自客户,这是勿庸置疑的。测试活动本来是一项风险驱动活动,在测试投入到达一定水平后,它的效果会迅速降低。对于“系统性”、“完备性”以及“严密性”,我不知道具体指得是什么?能不能详细说明一下,并介绍大家是如何做到需求的“系统性”、“完备性”以及“严密性”。

  问:敏捷设计开始设计的程序也可能是简单,不具有灵活性,直到需要变化时,团队才抓住机会应用敏捷设计原则去改进设计。这里有几个前提,团队应该对不良设计足够敏感,才能抓住改进设计的机会;团队有足够的时间去改进设计。如果这两个前提不成立,如果进行敏捷设计?

  答:怎样才具有灵活性呢?把东西做简单,简单的东西具有灵活性!KentBeck在《eXtremeProgramming》一书中对什么是简单做过明确的定义。用一句话来说,是:“cleancodethatworks.”如果这些前提不成立的话,那么什么设计都做不了。很多敏捷实践的目的是帮助我们通过学习、实践来培养这种敏感性。

  问:测试驱动开发过程中如何把握“前进的步伐”,即,每个测试用例的粒度如何把握?粒度大,可以加快开发速度,但又可能漏掉某些bug;粒度小,又影响开发进度。如何看待测试驱动开发过程中的测试用例?是单元测试吗?还是粒度很大的集成测试?如果是单元测试,至少也不应该是传统意义上的单元测试,此时的单元测试是属于黑盒测试还是白盒测试,或者既不是黑盒也不是白盒?如何理解测试驱动开发可以改进设计?有何理论根据?能够从黑盒测试的理论阐述这个问题吗?

  答:粒度是一个独立的、可以验证的东西。KentBeck在其《Test-DrivenDevelopment》一书中对使用TDD开发的节奏有详细的描述,我不再赘述。写测试觉得不会影响开发进度,越是在时间压力大的情况下,越是如此。我想大家都有过这样的经历吧:“花20分钟完成了一项功能,然后花2个小时甚至更多的时间去调试。”在TDD中,测试用例只用两种,面向客户的验收测试用例,和面向开发团队内部的内部测试用例(一般也称为单元测试)。为什么一定要那么清楚地区分黑盒和白盒呢?测试驱动开发能够改善设计的思想基础在《Test-DrivenDevelopment》有详细阐述。这和黑盒测试没有任何关系。TDD更是一种设计方法,一种有反馈、有验证的真正的设计方法。

  问:关于“软件之美”:对软件设计者来说,被简单、直观地分割,并具有小内部耦合的内部结构是美的。美的系统是灵活、易于理解的,构建、维护它们是一种快乐。在软件领域,如何审美?“灵活、易于理解的”这个概念含有很多主观性,对某一具体的软件审美,不同的人的评价是不一样的,大师级别的人当然更准确些,但大师级别的人太少了,那么,有没有一些客观的、可以量化的指标?使得没有很多经验的人,也可以以此为指引,改进软件使之向美的方向发展?

  答:《敏捷软件开发:原则、实践和模式》一书中给出了很多原则和实践方法,可以作为很好的参考。

  问:极限编程只适用于轻量级团队和项目,还是也适用于重量级团队和项目?和CMM等有无矛盾?在推行极限编程哪些可行(如测试驱动开发),哪些不可行(如结对编程)?在重量级团队和项目中如何运用?

  答:极限编程对于小型项目(10~20人)来说肯定没有问题。对于大型项目来说,照搬XP中的实践,肯定是会出问题的。所以需要一定程度的根据具体情况进行修正。关于和CMM有无矛盾的问题,这方面的讨论和文章有很多,基本上是见仁见智。不过,在提高开发质量这个目标上是肯定不矛盾的。其实,关于CMM本身该如何实施方面也存在很多不同意见,不同的评估师给出截然不同的结论的案例有很多。其实也没有必要非得全盘照搬XP不可,我觉得可以在不更改团队现有运作流程的情况下,先引入小部分实践,TDD应该是。

  问:5个重要的原则“单一职责原则、开放-封闭原则、Liskov替换原则、依赖倒置原则、接口隔离原则”虽然在此把它们表述为面向对象设计的原则,但是事实上它们只是软件工程中一直存在的原则的特例而已。那么,软件工程中一直存在的普遍性原则是什么?有哪些?在结构化编程还大量应用的嵌入式开发中,如何运用?“为使用而使用”设计原则会导致不必要的复杂性,设计原则是经验的总结,它必然是思考某个问题而得到的解决办法指导,那么,在编程当中,时刻要思考的问题有哪些?

  答:首先我得说一下,越是具有普遍性得原则,越不具有可实施性,只有针对特定context和force的原则才具有更多的实际意义,这也是模式为何在传播的设计经验方面得到普遍认可的重要原因。如果非要给出一个普遍原则的话,我觉得GradyBooch曾经说过的一句话可以作为参考:“Theentirehistoryofswenginereringisoneofrisinglevelsofabstraction.”不论你使用结构化编程还是面向对象编程,了解多种编程范型肯定会对你的开发带来好处。设计原则和模式只能为你指引方向,为重要的是要保持(设计)代码简单,时刻思考的问题是,这段代码是不是清晰地表达了我的意图,也是要intentionalprogramming,要“KeepItDRY,Shy,andTelltheOtherGuy.