当前位置:首页 > 计算机网络 > 软件工程/开发项目管理 > 测试驱动的面向对象软件开发
出版社:机械工业出版社
出版日期:2010年8月
ISBN:9787111304258
作者:Steve Freeman,Nat Pryce
页数:253页
章节摘录
这意味着在实践中我们可以把系统分成两个“世界”:值和对象。值以函数式的方式对待,对象则实现了系统有状态的行为。在第三部分,您会看到书中的编码风格是如何根据我们面对的世界而变化的。 在本书中,我们将使用术语“对象”来指具有标识符、状态和处理过程的实例,而不用于指值。似乎没有其他可以接受的术语同时包含这两种含义(如实体或过程)。 2.3 对象通信 只有当对象设计容易组合时,我们才能从这种高层次的、声明式的方式中获益。在实践中,这意味着它们遵循相同的通信模式,也意味着它们之间的依赖关系是显式的。通信模式是一组规则,决定了一组对象相互交谈的方式。这些规则包括它们扮演的角色、它们可以发送什么消息、何时可以发送等。在Java这样的语言中,我们可以利用(抽象的)接口来标识对象的角色,而不是利用(具体的)类——虽然接口不能定义任何我们想说的内容。 根据我们的观点,领域模型就在这些通信模型之中,因为正是它们为对象间可能的关系赋予了意义。以动态的、互相通信的结构来思考一个系统,这对于静态的分类来说是思考方式的巨大转变,而我们中的大多数人在刚接触对象时学到的都是静态的分类。领域模型甚至都不是明显可见的,因为在我们使用的编程语言中,通信模式没有明确表达出来。本书希望展示测试和模拟对象如何帮助我们更清楚地看到对象之间的通信。 这里有一个小例子,说明关注对象间的通信是怎样指导设计的。 在一个视频游戏中,对象可能包括:参与者(如玩家和敌人)、场景(玩家飞过的环境)、障碍(玩家遇上就会撞毁)、效果(如爆炸和烟雾)。还有一些脚本,它们在游戏过程中在后台大量生成对象。 从玩家的视角来说,这是一种很好的分类,因为它支持我们在玩游戏时需要做出的决定,也就是从外界与游戏进行交互时做决定。但是,对于实现这个游戏来说,这不是很有用的分类。游戏引擎必须显示可见的对象,告诉对象随时间产生动画效果,检测实体对象间的碰撞,并在实体对象发生碰撞时,把决定代理给碰撞处理器,如图2-2所示。 正如您在图2-2中看到的,这两种视角是不同的,一个是从游戏引擎的角度来看,另一个是从参与对象实现的角度来看。例如,障碍是可见的、实体的,而脚本是碰撞处理器和动画的,但不是可见的。游戏中的对象扮演了不同角色,取决于引擎当时对它们的需要。这种静态分类与动态通信之间的不匹配意味着,我们不太可能对游戏对象得到一个整齐的类层次结构,同时又能适合引擎的需要。 在最好的时候,类层次结构代表了应用的一个维度,它提供了一种机制,让对象之间能共享实现细节。例如,我们可能有一个基类来实现基于帧的动画的共同特征。在最坏的时候,我们曾看到许多代码库(包括我们自己的),充满了复杂性和重复,因为使用一种机制来表达多个概念。
前言
随着软件发布周期越来越短,一个困境出现了:如何在更少的时间里发布更多的软件,并持续地发布下去?我们需要新的观点来解决这个困境。只有技术的转变是不够的。 本书展示了这样一个新观点——假如软件不是“做”出来的,不像我们做纸飞机那样,叠好后就飞出去,情况会怎样呢?假如我们像对待有价值、有产出的农作物那样(培育、剪草、收割、施肥和灌溉)对待软件,情况会怎样呢?几十年或几个世纪以来,传统的农夫知道如何让农作物高产。如果我们以同样的方式对待程序,软件开发会有什么不同呢? 我印象最深的是,本书同时提供了这种观点转变的哲学思想和实现机制。本书的作者是善于写代码的实践者,他们也善于教别人写代码。您从中可以学到如何保持高产,以及如何重新审视您的程序。 这里展示的测试驱动开发的方式不同于我所使用的方式。虽然我还不能清晰表达其中的区别,但我已从作者清楚、自信的技巧介绍中受益。方言的多样化已经为我进一步优化开发提供了思考的新源泉。本书展示了一个有条理的、一致的开发体系,其中的不同技巧相互支持。 我建议您阅读本书,通过书中的例子,了解作者如何思考编程,如何实践编程。这种体验将丰富您的软件开发方式,有助于您编程,而且同样重要的是,有助于您以不同的观点来看待您的程序。
媒体关注与评论
“终于有一本书用丰富的代码揭示TDD和OOD之间的共生关系。本书值得保存。” ——Robert C.Martin “如果您想成为当前TDD领域的一名专家,就需要理解本书中的思想。” ——Michael Feathers
内容概要
Steve Freeman和Nat Pryce是独立的软件顾问,他们是英国的敏捷软件开发先锋。他们都曾在一些行业和组织机构中工作过:电信业系统开发、金融业、体育新闻报道和市场传播、IBM的薄膜包装应用、工业和学术研究机构等。他们是伦敦XpDay的创始人和组织者,经常出席和组织国际会议。Steve和Nat是几个有影响的开源项目的贡献者,这些项目支持TDD。在2006年,他们共同获得了敏捷联盟的Gordon Pask奖。他们住在英国伦敦。
书籍目录
对本书的赞誉
译者序
序
前言
作者简介
致谢
第一部分简介
第1章测试驱动开发的要点
1.1软件开发是一个学习过程
1.2反馈是基本工具
1.3支持变化的实践
1.4测试驱动开发简介
1.5大局
1.6用户场景测试
1.7测试的级别
1.8外部品质与内部品质
第2章测试驱动开发与对象
2.1对象之网
2.2值与对象
2.3对象通信
.2.4吩咐,不要问
2.5但有时要问
2.6对协作的对象执行单元测试
2.7用模拟对象支持TDD
第3章工具介绍
3.1如果您已了解这些框架,可以跳过本章
3.2JUnit 4简介
3.2.1测试用例
3.2.2断言
3.2.3预期异常
3.2.4测试装置
3.2.5测试执行者
3.3Hamcrest匹配器和assertThat()
3.4jMock2: 模拟对象
第二部分测试驱动开发过程
第4章启动测试驱动循环
4.1简介
4.2先测试一个可行走的骨架
4.3决定行走的骨架的形状
4.4创建反馈源
4.5尽早暴露不确定性
第5章保持测试驱动循环
5.1简介
5.2每个特征都从一个验收测试开始
5.3分离测量进度的测试和捕捉回归
错误的测试
5.4从最简单的成功场景开始测试
5.5编写您愿意读的测试
5.6看着测试失败
5.7从输入开发到输出开发
5.8针对行为进行单元测试,而非针对
方法
5.9聆听测试
5.10调整循环
第6章面向对象风格
6.1简介
6.2为可维护性而设计
6.3内部与同级的比较
6.4没有“与”、“或”、“但是”
6.5对象同级构造型
6.6组合比它的部分之和更简单
6.7上下文无关性
6.8正确地隐藏信息
6.9固执己见的观点
第7章实现面向对象设计
7.1先写测试怎样有助于设计
7.2通信比分类更重要
7.3值类型
7.4对象来自何处
7.4.1分解
7.4.2萌芽
7.4.3打包
7.5利用接口确定关系
7.6接口也要重构
7.7组合对象以描述系统行为
7.8迈向更高层的编程
7.9关于类
第8章基于第三方代码构建
8.1简介
8.2只模拟您拥有的类型
8.2.1不要模拟您不能修改的类型
8.2.2编写一个适配层
8.3在集成测试中模拟应用对象
第三部分工作的例子
第9章委托开发一个拍卖狙击者
9.1从头开始
9.2与一次拍卖通信
9.2.1拍卖协议
9.2.2XMPP消息
9.3安全实现目标
9.4这不是真的
第10章可行走的骨架
10.1从壁橱中取出骨架
10.2我们的第一个测试
10.3一些初始选择
10.3.1用户场景测试
10.3.2准备开始
第11章通过第一个测试
11.1构建测试的装配
11.1.1应用执行者
11.1.2伪造的拍卖
11.1.3消息代理
11.2测试失败和通过
11.2.1第一个用户界面
11.2.2显示狙击者状态
11.2.3连接到拍卖
11.2.4从拍卖接收回应
11.3必需的最小实现
第12章准备竞拍
12.1对市场的介绍
12.2针对竞拍的测试
12.2.1从测试开始
12.2.2扩展伪造的拍卖
12.2.3令人吃惊的失败
12.2.4由外至内开发
12.2.5对细节的无限关注
12.3AuctionMessageTranslator类
12.3.1提取出一个新类
12.3.2第一个单元测试
12.3.3完成用户界面循环
12.3.4我们实现了什么
12.4解析价格消息
12.4.1引入消息事件类型
12.4.2第二个测试
12.4.3发现进一步的工作
12.5完成工作
第13章狙击者发出竞拍出价
13.1引入AuctionSniper
13.1.1一个新类及其依赖关系
13.1.2关注、关注、关注
13.2发送竞拍出价
13.2.1Auction接口
13.2.2AuctionSniper发出竞拍出价
13.2.3利用AuctionSniper成功竞拍
13.2.4用户场景测试通过了
13.3整理实现
13.3.1提取出XMPPAuction
13.3.2提取用户界面
13.3.3整理翻译者类
13.4延迟决定
13.5自然发生的设计
第14章狙击者赢得拍卖
14.1先写一个失败的测试
14.2谁知道竞拍者
14.3狙击者还有话要说
14.4狙击者需要某种状态
14.5狙击者获胜
14.6取得稳定的进展
第15章迈向真正的用户界面
15.1更现实的实现
15.1.1接下来我们该做什么
15.1.2替换JLabel
15.1.3还是很丑
15.2显示价格细节
15.2.1先写一个失败的测试
15.2.2狙击者送出状态
15.2.3展现竞拍狙击者
15.3简化狙击者事件
15.3.1跟着感觉走
15.3.2重新确定sniperBidding()的目标
15.3.3填入数字
15.4更进一步
15.4.1转换胜利和失败
15.4.2修整表模型
15.4.3面向对象的列
15.4.4缩短事件路径
15.5最后润色
15.5.1针对列标题的测试
15.5.2实现TableModel
15.5.3目前已足够
15.6短评
15.6.1单一职责
15.6.2软件微创手术
15.6.3程序员过敏症
15.6.4庆贺思维转变
15.6.5这不是唯一的解决方案
第16章狙击多项物品
16.1针对多项物品的测试
16.1.1两件物品的故事
16.1.2ApplicationRunner类
16.1.3偏离主题,改进失败信息
16.1.4重新设计Main的结构
16.1.5扩展表模型
16.2通过用户界面添加物品
16.2.1更简单的设计
16.2.2更新测试
16.2.3添加一个动作条
16.2.4设计时刻
16.2.5另一层次的测试
16.2.6实现UserRequestListener
16.3短评
16.3.1取得稳定的进展
16.3.2TDD的秘密
16.3.3发布它
第17章分解Main
17.1发现角色
17.2提取Chat
17.2.1分离Chat
17.2.2封装Chat
17.2.3编写一个新测试
17.3提取Connection
17.4提取出SnipersTableModel
17.4.1狙击启动者类SniperLauncher
17.4.2狙击组合
17.5短评
17.5.1增量式架构
17.5.2三点不动
17.5.3动态设计的同时也进行静态设计
17.5.4对notToBeGCd的另一种修复方法
第18章填充细节
18.1更有用的应用
18.2适可而止
18.2.1引入落后状态
18.2.2第一个失败的测试
18.2.3输入停止价格
18.2.4传送停止价格
18.2.5约束AuctionSniper
18.3短评
18.3.1增量式设计用户界面
18.3.2其他建模技术也有用
18.3.3领域类型比字符串好
第19章处理失败
19.1如果它不能工作
19.2检测失败
19.3显示失败
19.4断开狙击者
19.5记录失败
19.5.1填充测试
19.5.2翻译者中的失败报告
19.5.3生成日志消息
19.5.4完成这次开发循环
19.6短评
19.6.1 “切香肠的逆过程”式开发
19.6.2用一些小方法来表达意图
19.6.3日志也是一项功能
第四部分可持续的测试驱动开发
第20章聆听测试
20.1简介
20.2我需要模拟一个不能替换的对象
20.2.1单例是依赖关系
20.2.2从过程到对象
20.2.3隐式依赖也是依赖
20.3记日志是一项功能
20.3.1通知而不是记日志
20.3.2但这种想法很疯狂
20.4模拟具体的类
20.5不要模拟值类型
20.6膨胀的构造方法
20.7令人困惑的对象
20.8太多依赖关系
20.9太多预期
20.10测试会告诉我们什么
第21章测试可读性
21.1简介
21.2测试名称描述功能
21.3规范的测试结构
21.4精简测试代码
21.4.1用结构来解释
21.4.2利用结构来共享
21.4.3强调正面
21.4.4代理给从属对象
21.5断言和预期
21.6具体值和变量
第22章构造复杂的测试数据
22.1简介
22.2测试数据建造者
22.3创建一些类似的对象
22.4组合建造者
22.5利用工厂方法强调领域模型
22.6从使用的角度消除重复
22.6.1首先,消除重复
22.6.2然后,让游戏升级
22.7沟通第一
第23章测试诊断
23.1要的就是失败
23.2小、专注、良好命名的测试
23.3解释性断言消息
23.4利用匹配器对象来突出细节
23.5自描述的值
23.6明显的预装值
23.7跟踪者对象
23.8明确断言预期得到满足
23.9诊断是一级功能
第24章测试的灵活性
24.1简介
24.2针对信息测试,而非针对表示方法
24.3准确断言
24.4准确预期
24.4.1准确的参数匹配
24.4.2允许和预期
24.4.3忽略不相关的对象
24.4.4调用次序
24.4.5jMock States的威力
24.4.6更为自由的预期
24.5“豚鼠”对象
第五部分高 级 主 题
第25章测试持久性
25.1简介
25.2隔离影响持久状态的那些测试
25.3明确测试的事务边界
25.4测试一个执行持久操作的对象
25.5测试对象能够持久
25.5.1来回转换持久对象
25.5.2来回转换相关的实体
25.6但数据库测试很慢
第26章单元测试与线程
26.1简介
26.2分离功能和并发策略
26.2.1并发地搜索拍卖
26.2.2引入Executor
26.2.3实现AuctionSearch
26.3对同步进行单元测试
26.3.1针对AuctionSearch的压力测试
26.3.2两次修复竞争条件
26.4对被动对象进行压力测试
26.5同步测试线程和后台的多线程
26.6单元压力测试的局限性
第27章测试异步代码
27.1简介
27.2取样或监听
27.3两种实现
27.3.1捕获通知
27.3.2轮询变更
27.3.3超时
27.3.4改进探测类
27.4轻易成功的测试
27.5错过更新
27.6测试没有效果的活动
27.7区分同步和断言
27.8事件源外部化
后记模拟对象简史
附录AjMock2速查手册
附录B编写Hamcrest Matcher
参考文献
编辑推荐
《测试驱动的面向对象软件开发》对于更快交付更好的软件,测试驱动开发(TDD)现在是一种已经确立的技术。TDD基于一个简单的思想:在写产品代码之前先写它的测试代码。但是,这个“简单”的思想需要一些技能和判断才能做得好。现在有了一本TDD实践指南。让您深入理解那些基本概念,并向您展示了如何让测试来引导开发,“培育”出一致的、可靠的。可维护的软件。 作者描述了他们使用的过程,努力实现的设计原则。以及完成工作的一些工具。通过一个详细实现的例子,您可以看到TDD如何在各个层次上工作,如何利用测试来驱动特征开发和代码的面向对象结构,如何利用模拟对象来发现并描述对象之间的关系。在这个过程中。《测试驱动的面向对象软件开发》系统地讨论了开发团队在使用TDD时遇到的挑战——从过程中集成TDD到测试最难的特征。 旧代码带来的新思维,Robert C.Martin高度评价,Kent Berk作序推荐。 《测试驱动的面向对象软件开发》包括以下内容: ●如何有效实现TDD:启动,然后在整个项目中保持你们的冲劲。 ●如何创建更干净的、更有表现力的、更可维护的代码。 ●如何利用测试。对可持续的品质保持最严格的关注。 ●理解在真实软件开发的环境中,TDD、模拟对象、面向对象设计如何交织在一起。 ●如何利用模拟对象来指导面向对象设计。 ●如何在TDD困难的地方取得成功:管理复杂的测试数据。测试持久层和并发。
作者简介
《测试驱动的面向对象软件开发》采用通俗易懂的比喻,众所周知的编程语言,短小精悍的工作实例,深入浅出的分析处理——仿佛在和几位世界级的编程高手一边喝茶,一边聊天,循序渐进地让读者在不知不觉中进入编程的最高境界。即使是刚刚入门的初学者,也会从中找到读书的乐趣,因为可以从一开始就找到开启面向对象开发大门的钥匙;随着经验的积累,编程水平的提高,再来看这本书,用不同的视角重新审视程序,又会体会到更深层的编程哲学。
本书是编程爱好者的启蒙指南,更是系统分析人员、测试人员、程序设计人员、软件开发人员以及面向对象程序研究人员等专业人士革新编程思想的必备手册。
图书封面