本书主要介绍了利用主流开发方法学和技术技巧进行面向对象开发的原则与实践,通过完整剖析一个实际应用程序的设计、开发与实现,深入浅出地阐述OOD(面向对象开发)、OOP(面向对象程序设计)、TDD(测试驱动开发)、UT(单元测试)等开发方法学与最佳实践的应用与技术技巧,全面展现深厚技术实践经验的精髓。全书内容连贯、一气呵成,以实践阐述理论,以理论知道实践,是理论结合实践的典范之作。
第0章 导读 (1)
第1章 一个简单的想法 (7)
1.1 找寻问题的本质 (13)
1.2 搜寻解决方法 (15)
1.2.1 面向对象开发方法 (15)
1.2.2 测试驱动开发(TDD-Test-Driven Development) (16)
1.2.3 结合面向对象分析/面向对象设计和XP/TDD (16)
1.3 结论 (17)
第2章 分析和设计架构的思考 (19)
2.1 从自然的场景开始构思 (20)
2.2 PFM系统的设计 (22)
2.2.1 需求捕获 (23)
2.2.2 使用需求分析 (24)
2.2.3 产品设计 (27)
2.3 类架构的思考 (34)
2.4 建立开发环境 (36)
2.4.1 建立版本控制项目 (37)
2.5 结论 (42)
第3章 TDD和DUnit框架 (45)
3.1 取得DUnit For .NET (45)
3.2 测试驱动开发模型 (46)
3.3 使用DUnit/DUnit For .NET框架 (47)
3.3.1 范例场景 (48)
3.3.2 在Delphi项目中使用DUnit.NET (49)
3.3.3 使用DUnit.NET框架建立测试用例 (50)
3.3.4 DUnit.NET框架提供测试服务的函数 (59)
3.3.5 使用测试包(Test Suite) (61)
3.4 Delphi 2005对于TDD的支持 (68)
3.4.1 建立本章范例项目 (69)
3.4.2 使用测试用例向导建立测试用例项目 (70)
3.4.3 使用测试案例向导建立测试案例骨架程序代码 (71)
3.4.4 在Delphi 2005集成开发环境中执行测试用例 (76)
3.5 结论 (77)
第4章 执行引擎和XML驱动设计 79)
4.1 设计架构的思考 (80)
4.2 设定本章开发项目 (85)
4.3 封装配置信息类设计 (89)
4.3.1 TPFMConfig类的设计 (90)
4.3.2 TPFMConfigManager类的设计 (91)
4.3.3 TPFMSchedule类设计 (93)
4.3.4 TPFMScheduleManager类设计 (93)
4.4 从面向对象分析/设计转换到XP/TDD (95)
4.4.1 TPFMConfigManager类实现 (96)
4.4.2 TPFMScheduleManager类实现 (100)
4.4.3 建立测试用例测试设计和实现的类 (103)
4.5 观察到父类的迹象 (111)
4.5.1 设计TPFMManager (113)
4.5.2 使用TDD测试TPFMManager (117)
4.6 改善和重构TPFMManager类 (120)
4.7 我们学到了什么 (127)
4.8 开发周期管理 (128)
4.9 结论 (132)
第5章 多元,弹性架构的设计和实现-Handlers (135)
5.1 设计架构的思考 (136)
5.2 设定本章开发项目 (143)
5.3 处理者接口和处理者类的设计和实现 (144)
5.4 处理者类派生类设计和实现 (147)
5.4.1 文件处理者类 (147)
5.4.2 压缩和反压缩处理者类 (150)
5.4.3 加密和解密处理者类 (155)
5.4.4 目录处理者类 (159)
5.5 处理者工厂类设计和实现 (162)
5.5.1 处理者Factory类 (162)
5.5.2 测试处理者Factory类 (164)
5.5.3 进一步改善试处理者Factory类 (166)
5.5.4 测试处理者Factory类 (169)
5.5.5 为每一个处理者类建立独立的工厂类 (170)
5.5.6 测试处理者Factory类 (173)
5.6 Check In本章的源程序 (173)
5.7 处理者类和处理者工厂类的改善 (174)
5.8 结论 (175)
第6章 搜寻处理目标的设计和实现-Finders (177)
6.1 搜寻处理目标类的思考和设计 (177)
6.2 设定本章开发项目 (180)
6.3 通用搜寻类-TFinder (182)
6.4 目标文件搜寻类-TFileFinder (183)
6.5 使用Factory设计模式-TFinderFactory (187)
6.6 封装处理目标类-TCandidate (188)
6.7 使用TDD测试类设计和实现 (189)
6.8 程序代码风格的讨论 (191)
6.8.1 TFinder和TFileFinder类的改善 (191)
6.9 结论 (198)
第7章 封装处理目标 (199)
7.1 设定本章开发环境 (201)
7.2 TCandidateFactory类 (202)
7.3 修改TCandidate类 (203)
7.4 修改客户端程序代码 (205)
7.5 重新使用TDD测试修改后的TCandidate类 (206)
7.6 结论 (209)
第8章 谁执行串联和集成的工作? Coordinator和Task (211)
8.1 设计架构的思考 (212)
8.1.1 类架构设计 (215)
8.1.2 类互动 (218)
8.2 建立本章开发项目 (219)
8.3 类的设计和实现 (221)
8.3.1 使用Façade设计模式 (221)
8.3.2 不光是提供Façade功能 (223)
8.4 工作分派类TPFMTaskDispatcher (224)
8.4.1 TPFMTaskDispatcher类的设计和实现 (224)
8.4.2 修改TPFMCoordinator使用TPFMTaskDispatcher类 (227)
8.4.3 修改TPFMManager类 (227)
8.5 以工作指派思想设计PFM需要执行的工作-TPFMTask (230)
8.5.1 采用接口设计 (230)
8.5.2 工作类设计 (232)
8.5.3 TPFMTask工作类的实现 (233)
8.5.4 TScheduledTask类的设计和实现 (236)
8.5.5 TSpecifiedTask类的设计和实现 (237)
8.6 使用TDD进行测试 (237)
8.7 TPFMTask的工厂类 (242)
8.7.1 使用TDD测试TPFMTaskFactory (244)
8.8 改善TPFMTaskDispatcher类 (246)
8.8.1 为TPFMTaskDispatcher加入对象池机制 (248)
8.8.2 修改TPFMTaskDispatcher类相关的方法 (256)
8.8.3 测试用例可以帮助我们进行所有的测试吗 (257)
8.9 Check In本章源程序 (265)
8.10 结论 (266)
第9章 如何永续存储?数据库处理者和Adapter (269)
9.1 设计架构的思考 (269)
9.2 准备本章范例项目 (272)
9.3 TPFMDBAdapter类 (275)
9.4 TPFMDBBKAdapter类 (276)
9.5 修改TDBHandler类 (285)
9.6 使用TDD测试数据库处理者类 (286)
9.7 结论 (290)
第10章 Package和Assembly的设计 (293)
10.1 封装架构的思考 (294)
10.1.1 如何重新组织Delphi程序单元文件 (294)
10.2 准备本章范例项目 (299)
10.3 从最简单的地方开始——例外Assembly (302)
10.4 开发PFMSystemConfigurations包 (304)
10..5 开发PFMSystemCandidate 包 (305)
10.6 开发Finders Assembly (306)
10.7 开发处理者Assembly (307)
10.8 开发PFM系统核心Assembly (308)
10.9 如何确定Assembly能够正确地工作 (310)
10.9 结论 (317)
第11章 让我们完工吧,OO和RAD (319)
11.1 准备本章的开发环境 (319)
11.2 如何撰写常驻在Windows工具栏上的.NET程序 (321)
11.2.1 自定义ApplicationContext对象 (323)
11.2.2 修改Delphi.NET主程序 (326)
11.3 如何设定系统时钟触发PFM系统的服务 (327)
11.4 集成PFM主程序和PFM类 (328)
11.5 Ready,Set,Go (330)
11.6 测试PFM主程序 (331)
11.7 让PFM主程序更具响应性 (333)
11.7.1 更准确地显示时间 (333)
11.7.2 PFM系统工作时改变程序显示的图像 (334)
11.8 保存PFM系统主程序 (335)
11.9 结论 (335)
第12章 回到RAD,图形用户界面和组件 (337)
12.1 PFM公用程序设计思考 (338)
12.2 准备本章开发环境 (339)
12.3 PFM公用主程序 (341)
12.3.1 PFM公用程序定义程序单元 (342)
12.3.2 PFM公用主程序单元 (342)
12.3.3 PFM公用程序辅助类 (348)
12.4 执行PFM公用程序 (353)
12.5 保存本章开发结果 (357)
12.6 结论 (358)
第13章 撰写高效率的.NET应用程序 (359)
13.1 影响.NET执行效率的因素 (359)
13.1.1 虚拟堆栈机器 (360)
13.1.2 即时编译器(JIT) (362)
13.1.3 最优化机器编译器 (364)
13.1.4 正确使用.NET机制和Framework (367)
13.2 撰写高效率.NET应用程序 (370)
13.2.1 和垃圾回收器(Garbage Collection)协作 (370)
13.2.2 更好地使用Collection类 (375)
13.2.3 了解引用对象和数值对象的使用 (378)
13.2.4 Boxing/Unboxing (383)
13.2.5 字符串处理的陷阱 (386)
13.2.6 小心使用Reflection (388)
13.2.7 使用效率监督工具 (388)
13.3 一些通用的建议 (389)
13.4 结论 (391)
第14章 更多的设计和实现,您能继续吗 (393)
结束语 (397)
作为一位IT人员,您常阅读什么样的专业书籍呢?是喜欢偏向程序语言和系统的书还是目前流行的软件工程书籍?是喜欢讨论程序技巧的书籍还是设计架构的书呢?说实在的这些笔者都喜欢,尤其是工作需要时一定得阅读所有必要的信息,不过一个有趣的问题是在阅读每一本技术书籍时您会有什么样的感觉?
当笔者阅读有关偏向程序语言和系统的书籍时,例如Delphi/C#/Java/.NET Framework等,脑中却常常在想如何和软件工程以及设计架构结合在一起,因为这些书籍讨论的主要是实现技术,但是许多专家不是告诉我们使用专业的开发流程和设计架构的是影响软件开发更重要因素吗?
当笔者阅读有关软件工程方面的书籍时,也常常觉得不同的软件工程似乎适合不同风格的IT人员和组织使用,有的IT人员非常严谨,他们喜欢使用拥有正式、一定流程的软件工程来发展软件。而有的IT人员则非常喜欢自由风格,开发软件也非常具有弹性,他们喜欢极为灵活的软件工程,然而有更多的IT人员介于这两者之间。不同的IT人员使用不同的程序语言,因为不同的IT人员有着不同的应用,或者对于程序语言有着不同的喜好,这是很自然的事情。软件工程也应该是一样的,不同的组织适用不同的软件工程或是喜好不同的软件工程。例如RUP对于笔者个人而言感觉太沉重,而完全使用XP又让笔者觉得有些单薄,因为笔者还是喜欢进行先期的基础设计。当笔者阅读系统架构的书籍时经常看到许多作者和专业人员询问:要“多少的设计才足够?”。就笔者在工作的经验来说,过多的设计的确会造成失败的结果,请注意笔者在这里说的失败是指软件无法在限制的时程中完成。
最后一个笔者最常思考的问题是我们应该如何结合不同的程序语言、系统架构、软件工程等等来开发软件?例如当笔者阅读XP的书籍时觉得很棒,因此接下来的软件开发就自然受到XP的影响,但是笔者以前使用、喜欢和接受的OOA/OOD呢?TDD(Test-Driven Development)很酷,改变了笔者的想法、视野以及开发软件的方法,但是TDD一定只能和XP使用吗?不能和设计导向的开发方式一起使用吗?这似乎也不尽然。
对于许多使用Delphi的开发人员来说,可能习惯了使用RAD开发模式,因此许多Delphi开发人员并不熟悉如何使用面向对象的方式来开发软件。使用RAD并没有问题,RAD如果加上良好的架构仍然可以开发出很棒的软件,RAD加上TDD可以产生快速而质量优秀的软件,然而不可否认的是,现在我们身处的开发环境几乎都是面向对象的框架(Framework)、程序语言和集成开发环境了,因此开始试着结合RAD、面向对象、面向对象分析/面向对象设计、TDD等应该能够让Delphi的开发人员学习到更多的观念和技术,不但可以提升生产力、增加软件的质量,也可以了解C++/Java那边的开发人员如何开发软件。结合RAD和面向对象能够提供更强大的力量,至少笔者是如此体会的。
在笔者阅读许多的IT书籍时,最喜欢看的是结合技术/理论从头设计软件的一本IT书籍,这个场景软件无须很大,只须完整地讨论从分析/设计到如何实现出来即可。这个发展过程应该说明设计是如何出的,也就是说,类图(Class Diagram)之中的类、类架构、类中的PME(Property,Method和Event)是如何找出来的,也要说明如何根据设计架构实现出软件,在实现过程中会发生什么事?实现如何结合设计等细节。可惜的是这样的书很少,大多的书不是偏重设计讨论,不然就是用一堆程序代码展示程序代码技巧而已。笔者相信在许多OOA/OOD中漂漂亮亮,设计良好的类图或是设计架构绝不是那些作者第一次就能画/设计出来的,一定经过某些的刺激/化学作用才出现的,类中的PME也是一样,问题是这些刺激/化学作用是什么?
还是言归正传,那么本书的主要讨论内容是什么呢?很简单,本书将从一个笔者以前使用RAD方式开发的小工具为起点,讨论如何使用OOA/OOD并且结合XP/TDD(Test-Driven Development)来实现这个工具。在整个的设计和实现流程中读者将会实际地看到如何使用面向对象技术以及敏捷开发方式来完成软件开发的工作。读者将会学习到如何把用户需求借助OOA/OOD转换为观念上的设计,当然这会产生用户案例(Use Case)、类图、循序图(Sequence Diagram)甚至是活动图(Activity Diagram),不过最重要的是借助书中的讨论、观察和设计,读者可以真正看到类架构是如何形成的。在形成了初步的设计之后本书会结合敏捷开发和TDD来快速进入实现阶段,而在使用敏捷开发和TDD的过程中,我们又会发现这个步骤可以更进一步地让我们了解在OOA/OOD阶段的盲点并且让我们能够再精致化原先的设计。笔者发现这样的结合非常有效果,不但设计架构能够真正反映实现的程序代码,而且几乎所有的实现程序代码又都能够被TDD所验证,这样的结果使开发人员对于进行的设计和实现的程序代码都拥有高度的信心,这是笔者在没有这样做之前从来没有的感觉(如果读者真正开发过大型的项目就可以了解笔者说的,当项目实现的程序代码愈来愈多时,到了最后就会愈来愈心虚)。
因此,本书主要是给习惯使用RAD方式而想学习如何使用OOA/OOD/XP/TDD开发软件的Delphi开发人员阅读的,如果您已经是OOA/OOD的专家,那么您就不需要阅读本书。本书除了可以让Delphi开发人员学习如何使用OOA/OOD/XP/TDD之外,在本书讨论的过程中读者也可以看到设计样例(Design Pattern)如何自然地出现在我们的设计中并且实现在程序代码中,本书另外一个附加的功能则是读者也可以在本书中学习到许多.NET程序设计的技巧。
在十年前笔者使用C/C++学习OOA/OOD时也曾经迷惘过,不知道如何设计面向对象应用程序,经过这些年工作的历练,笔者认为学习OOA/OOD也和学习程序语言和程序设计一样,只要具备扎实基础知识再加上多看、多听、多学、多练就可以具备一定的技巧和经验,之后就像使用Delphi一样会发现这些技能都是很自然的。开放的学习之心、积极的学习态度和追求更好的欲望可以让开发人员成为IT领域的顶尖人才,笔者在此也鼓励Delphi的开发人员能够顺利地从RAD进入面向对象的世界,进而结合RAD/面向对象让Delphi能够发挥比其它程序语言/工具更为强大的开发能力。
利瓦伊 7/2004于台北新店