接下来抽象出SearchEngine的接口ISearchEngine,并让SearchEngine实现该接口。其中接口方法包括ExactSearch和BlurSearch方法。将前面的测试代码作小小的修改,修改后同样需要在NUnit中运行,保证顺利通过:
[Test]
public void TestSearching()
{
ISearchEngine engine = new SearchEngine();
Assert.IsNotNull(engine);
……
}
考察SearchResult类型,该类型的对象应该在整个程序中只保留一个对象,因此,应对此采用单例模式。修改测试代码:
[Test]
public void TestSearching()
{
ISearchEngine engine = SearchEngine.Instante;
Assert.IsNotNull(engine);
……
}
根据测试代码修改程序代码,将SearchResult类型的构造函数改为private,并提供只读的静态属性Instante,以此来获得单例对象。
仅仅是这样还不够的。考虑到搜索的范围有多种情况,如internet,local machine,DB等。SearchEngine类型应该具体化不同类型,并同时实现ISearchEngine接口。例如搜索范围在internet,测试代码如下:
[Test]
public void TestInternetSearching()
{
ISearchEngine engine = InternetSearchEngine.Instante;
Assert.IsNotNull(engine);
……
}
既然有如此多的类型,类型的创建就必须通过工厂进行管理。此时测试代码需要做进一步的修改:
[Test]
public void TestInternetSearching()
{
ISearchEngineFacotry fatory = new InternetSearchEngineFactory();
ISearchEngine engine = factory.CreateInstante(“Internet”);
Assert.IsNotNull(engine);
……
}
同理,我们应该分别实现测试方法TestLocalSearching()和TestDBSearching()。
按照这样的思路,分别对存储功能和显示功能进行重构。记住,每做一步重构,都需要严格按照TDD的方式。首先写出测试代码,然后在NUnit运行。如果是红灯,需要写出相应的代码,再运行NUnit,直到全部均为绿灯为止。
三、第一步的小结
表面上看,这样繁复地写测试代码,程序代码,确实是有些Kill Time了。但我们需要认真地思考所谓“发现价值”的意义。通过测试先行的方式,以模拟客户应用的状态来考量客户的需求,并通过此驱动程序员一步一步地到达“生产价值”的终点。“发现”与“生产”并行不悖,同时“质检员”一直跟随其间,保证了产品的质量。
就好比Nike鞋的生产,必须以体贴用户的角度出发,设计出吸引人的样式,那么大规模的生产才会有盈利的可能。
TDD的生产过程也许慢了一点,但请不要忽略了它其实已经省去了编码后单元测试的时间。相加相减之后,又会浪费多少时间呢?所以,千万不要以“时间紧”的理由来搪塞我哦。
四、考察第三步——收获价值
传统的方式,在产品生产出来之后,紧接着的是大量的测试,其中也包括单元测试;最后收获了产品、一大堆源代码和文档。而TDD的方式,既省去了单元测试的过程,同时还收获了另外一样上帝赐予的礼物——测试类或测试套件。
测试类绝对是一件奇妙的礼物。必须认识到它的价值不只是在于“发现价值”的阶段,它同样是我们的“收获”。
第一:比代码更好的文档、比文档更好的代码
有了它,不用钻进浩如烟海的文档里,四顾茫然了。文档的文字描述既不准确,容易产生歧义,又容易产生文档同步的问题。也许它能促进你对业务和架构的理解,但对于程序本身,你无法从文档中得到基本的启示。
那么看程序的源代码吗?你会在众多的类对象和方法中绕来绕去,最后一头雾水,精疲力尽之后,还是一无所获。
而看测试代码就不同了,你不需要了解每个方法的具体实现,因为测试代码是从客户的应用角度来书写的,看完测试代码,你会很轻松地理清程序结构的脉络。
第二:新兵训练营的绝佳教材
也许你的项目组新进了员工,如果他熟悉TDD,那么,这些测试类是他熟悉项目的最好文档;如果他还没听说过TDD,不用着急,先把这些测试类给他。只要他不是程序设计的新手,我想这个新兵会很快熟悉项目组开发的方式。再让他写几个测试样例,他会立即投入到TDD的怀抱中来的。
第三:满载而归的信心
项目开发中,成员最宝贵的除了认真、努力、团队精神之外,就是信心了。这里所谓的信心,并非是对自己能力充满乐观的估计和客观地评价后,表现出来的精神面貌,而指的是程序员对代码正确性的信心。无论这些代码是自己写的,还是他人写的,只要严格按照TDD的要求进行,你都会对它们充满信心。虽然不能保证没有bug,但必须承认的是通过单元测试,我们已经将bug降低到最小了。
五、结论
中国企业在企业运行价值链上,走好了利润最低的第二步,却忽略了“发现价值”和“收获价值”对于一个企业的重要性。韩国三星在几年之前还是一个亏损600多亿美元的企业,如今它已经成功地扭亏为盈,并跻身世界五百强。原因很多,但不可忽视的是,他在价值链的首尾两步中作得很好。从高端产品中发现价值,找到了目标市场;从品牌创造中收获了价值,走向了世界。
我不是说软件开发一定要采用TDD的方式,它自然也有很多缺陷。然而,我们在开发的过程中,同样要重视设计的“发现价值”阶段,然后在收获产品的同时,不要忽略了还应该收获其他同样值得珍视的“价值”。从这一点来看,也许TDD更符合这种价值链的模式。而我们程序员千万不要舍本逐末,过于偏执地重视“生产价值”,以致于在软件开发方法上,总是落后于人,进而受制于人!
最后,谨以我之愚见,思考TDD的方式,认为TDD内力精深,大约分为四种无上之力:
1、驱动力——驱动程序代码编写;
2、学习力——新兵训练营之绝佳教材;
3、自信力与他信力——bug降到最低;
4、控制力——与重构紧密接合,牢牢控制开发过程。
更多软考资料请访问:考试吧软件水平考试栏目
希望与更多网友交流,请进入考试吧软件水平考试论坛
- 推荐给朋友
- 收藏此页
·2006年下半年软考《信息系统监理师》试题分析 (2006-11-8 9:02:02)
·2006年下半年软件水平考试《信息系统监理师》试题 (2006-11-6 10:38:41)
·2006年软件水平《信息系统监理师》试题 (2006-5-31 16:49:14)