首页>参考读物>计算机科学与技术>软件与程序设计

软件再工程:优化现有软件系统的方法与最佳实践
作者 : (美)Bradley Irby 著
译者 : 张帆 翟林丰 译
出版日期 : 2014-03-10
ISBN : 978-7-111-44881-5
定价 : 69.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 265
开本 : 16
原书名 : Reengineering .NET: Injecting Quality, Testability, and Architecture into Existing Systems
原出版社: Pearson Education Asia
属性分类: 店面
包含CD :
绝版 : 未绝版
图书简介

图书特色

Bradley Irby 资深软件架构师和CTO,拥有20余年行业经验,擅长软件再工程和软件迁移,在提升和改善旧版系统的质量和稳定性方面有丰富的经验。曾将多个基于VB6、ASP_Classic和早期.NET版本的应用再工程为当前体系结构和最新质量方法下的现代应用。凭借其高超的技艺,再工程一个200万行代码的.NET应用,而该过程几乎是零缺陷。与此同时,他也擅长在不关闭和不停止功能开发的情况下更新应用程序,赢得客户广泛好评。他还常为知名公司和政府部门开发高度定制的系统和应用,是旧金山.NET用户联盟管理者,常在全美发表演讲。
随着软件使用时间的增长,很多应用和系统迅速落后于现实应用世界,而且变得脆弱:难于修复、管理、使用和改进。作者结合多年软件再工程经验着重介绍了如何在不影响生产和服务的前提下,将新的架构和先进的特性集成到既有的关键业务系统的最佳实践,使.NET代码获得新生。本书使用一种循序渐进的方法,结合大量代码和案例,传授使系统变得更可靠、实用和易于维护的技术,为企业经济、便捷地解决系统老化问题提供方法指南。
覆盖内容包括:
在不破坏软件的前提下,将旧版.NET软件迁移到更加灵活、广泛和可维护的架构中;
采用MVC、MVP和MVVM模式重构Web应用程序;
提出正确的问题,以预测可能发生的重构问题;
规划和组织再工程项目,在恰当的时间将合适的技术运用到每一个任务;
采用创新的双重测试使得单元测试更加有效;
应用依赖倒置打破紧耦合,并促进开发和测试;
应用源代码控制、缺陷跟踪和持续集成;
在未接触业务逻辑之前,通过“清理”旧版解决方案进行改善;
建立坚实的开发基础结构以支持再工程项目;
重构服务,涵盖知识库、域模型和命令调度程序的使用等高级技术;
重构控制器/视图或视图模型/视图对。
对于所有开发人员、架构师和项目经理,以及那些想要了解再工程项目中团队所面临的独特挑战的大量非技术型管理人员和首席技术官来说,本书不容错过!

图书前言

什么是软件再工程
  任何一个有多年工作经验的软件开发者都曾经面临过这样一个困难的局面:如何改进应用程序。这种困难之处包括:浏览代码很困难,确定从哪里开始追踪缺陷很困难,对缺陷进行修复也很困难。总之,关于应用程序的所有一切都很难。改进和修复缺陷耗时长、风险高而且代价大。
  解决旧版应用程序问题的一种可能的选择是:离线一年或更久的时间,从头开始重写。通常情况下,这些应用程序对业务运营是非常关键的,所以,功能开发不能停滞如此长的一段时间。因此,对旧版应用程序的修复工作需要不间断地进行,以期在下一个发布周期之前修复所有缺陷并推出补丁。
  此外,还有一种选择来帮助解决这些旧版系统的问题,那就是“软件再工程”。
什么是旧软件
  一个应用程序构建完成后,就会立即步入老化的过程。软件工程是一门年轻的学科,构建应用程序的方法每天都在推陈出新。随着业界不断引入新的开发工具,如果不更新现有的应用程序从而使用这些工具,那么它们会变得越来越难以维护。
软件老化的原因
  软件老化有很多原因。最明显的原因莫过于当今世界科学技术的飞速发展。几年前才开发的软件技术很快就会变得陈旧,并且难以维护。快速的工作变动正在成为一种潮流,这同样加剧了代码质量的下降。随着原先的开发人员转投新的公司,关于代码结构设计的最初的一些理念就会丢失,导致留下的开发人员拼尽全力收拾残局。
  然而,通过使用软件再工程持续不断地改进系统,这种对原代码设计者的依赖程度就会削弱。新的开发人员也能很容易适应和了解系统的架构,这主要是因为系统的架构将是与时俱进的,同时在网络上也可以找到很多有用的信息。
警示标志
  特定标志可以警示一个系统是否真的到了需要再工程的时候。
开发者对功能请求存在抵触情绪
  如果开发人员抵制来自于管理人员或用户的功能请求,不愿意改进应用程序,那么很有可能是因为该系统真的已经到了举步维艰的地步。随着时间的推移,该软件应用会变得非常脆弱,从而导致任何功能的开发都变得极其困难且令人沮丧。
发布后存在着大量缺陷修复工作
  如果开发团队在软件新版本发布后马上就面临缺陷警告,则表明软件在开发过程中并没有使用现代的质量保证工具。为了显著减少缺陷率,部分软件再工程流程需要引入这些自动化的质量保证工具。
软件质量问题长期存在
  旧软件中缺陷及其修复工作的多少显示了旧软件的老化程度。软件的老化和脆弱程度越高,做非破坏性的修复就越难。如果你发现,每当刚修复一个缺陷,马上就有两个或者更多的缺陷涌现出来的时候,那么说明这个应用程序需要进行再工程。
  由于不支持诸如单元测试和系统模拟等新的质量保证方法,旧版应用程序特别容易出现质量问题。如果不使用这些工具,那么在系统修复时所产生的那些缺陷,看上去会与刚刚所做的修复完全无关。
软件再工程的目标和优点
  软件再工程的目标是通过引入现代的架构和软件开发技术来逐步改善现有系统,同时在保证在线的情况下,持续不断地为系统增加新的功能。这意味着对目前已有的系统来说,我们无须费尽心思重写代码。通过软件再工程,我们可以有条不紊地改进现有系统,使之逐渐达到符合最新的软件开发标准的水平。在整个软件再工程项目期间,系统随时都可以进行产品发布。换句话说,这就好比我们可以在飞机飞行的同时对飞机进行维修。
引入现代架构
  软件系统的架构决定了需要建立的必要细节的数量。有的时候,我们试图使用最新的方法为一个旧系统建立一种数据输入的形式,这就像是为一架双翼飞机加上一个喷气式发动机一样,这样做飞机就算飞离地面也飞行不了多久。
  大多数管理者听到“需要更新架构”的第一反应就是应用程序必须重写。这并不一定正确。事实上,只要保证新的组件在接入的过程中,始终保持一个合理的步骤和顺序,那么架构的更新就可以逐步实现。
  引入新架构无须劳师动众。不管开发团队有多少人,或者现有系统有多少行代码,新架构的引入完全可以由一个小团队甚至一个独立的设计师来完成。引入新架构的每一步都是独立的,并且不影响应用程序的其余部分。引入新架构和质量管理无须大量的预算或者专家团队。
在线增加新功能
  本书中关于如何在线增加新功能的所有步骤都是特别设计的,这样既保证了这些步骤不会对其他开发造成干扰,同时保证了这些步骤之间可以并发进行。这些新功能的结构也是特别设计的,为的是保证引入的新功能不会带来任何不利影响,并在完成时通过几行代码就可启用新功能。这确保:在前端,产品经理能够持续不断地接受产品新的功能请求,发布更新的版本;在后台,每个新的版本都会在前一版本的基础上有所改进。
  对于任何一个新增的功能,如果它需要一个独立程序开发员花费一整天的时间来完成,那么为该应用增加新功能的过程将会被重新分解成多个小的步骤。这样做的目的在于:一方面,保证该应用的部分功能能够持续更新;另一方面,保证该应用的其他部分功能仍然能够使用旧的结构。
  随着该应用每一个部分的逐步更新,应用程序将会变得更可测,缺陷率也会大幅度地降低。
灵活使用敏捷方法
  很多开发公司都采用敏捷开发策略。对于不熟悉这种方法的公司来说,敏捷开发可以简单地解释成快速周期开发。这种周期(又称为“冲刺”)通常以几天或者几周来度量。每个快速周期开发结束时,应用程序处于一个潜在可发布状态。
  保持应用程序处于一个潜在可发布状态,就是软件再工程。每一次所做的更新都必须是完整和独立的,这样才能够保证在提交代码的时候,一方面系统仍然可以正常运行;另一方面系统能够处在一个稳步提升质量的过程中。这就是本书在设计这些步骤时所遵循的设计方法。每个步骤都可以在一个冲刺阶段中完成,而这往往是一天。极少数软件再工程的工作需要比较长的时间。这样的工作就需要特殊设计,以保证当它们还没完成,或者完成一半的时候,整个系统受到的影响也是微乎其微的:系统可以照常运行,只不过部分功能已经进行过更新,部分功能还处于旧版本的状态下。
降低风险
  一个软件系统使用多年之后,用户就会形成对该软件系统固定的业务流程操作模式。重写整个系统会破坏这些未文档化的业务流程,逼迫用户在工作流中使用新系统。
  软件再工程维持了工作中的这些未文档化的流程。通过在现有系统上慢慢引入新的架构,这些流程就可以不受干扰。如果引入新架构确实以某种形式扰乱了正常的业务流程,那么一定会有一个及时的反馈,通常情况下,应用软件的产品化必须是快速而敏捷的。
降低成本
  从头重写系统要求对所有业务逻辑的开发也要推倒重来。对于一个旧版系统来说,重写软件摈弃了之前投入的大量时间和知识,而事实上这些时间和知识在软件重写过程中不可避免地需要被重新创建。
  再工程尽可能地复用现有的业务逻辑代码,从而可以显著节省大量的时间和金钱。在再工程项目中,有显著数量的任务可以跳过而无须改动。而这些任务的总体数量是非常可观的。由于现有系统已包含绝大多数的需求,所以只需新增极少数的需求文档。这可以为需求分析人员节省下几周甚至几个月的调研和归档用户需求的时间。有了实现这些需求的业务逻辑,会节省更多的时间。
  1990 年,W.M. Ulrich 为《American Programmer 》杂志的十月刊撰写了一篇文章。在文章中,他描述了一个商业系统,该系统完全重写的成本约为5 亿美金。事实上,该系统成功地进行了再工程,其总成本仅为1.2 亿美金。相比全新的开发,再工程是非常经济的。
本书的读者对象
  本书适合从事维护和运行系统工作的读者。对于技术经理和产品经理来说,本书描述了提高系统可靠性的必要过程,其使得系统运行更快,更易维护以及拥有更少的缺陷。对于架构师和开发人员来说,本书包含了新架构的选择方法以及完成关键部分的必要代码的详细描述。对于通过添加现代架构和自动化测试方法增量地改进应用程序的结构和质量,本书给出了详细的建议。按照本书中概括的步骤,可以提高应用程序的质量并使得添加新功能变得更加容易和快速。
  再工程一个现有系统比从头开始构建一个等效的系统更加容易、便宜且风险低。如果你遵循本书中总结的建议,就可以提高开发的速度和最终的质量,同时还可以保持系统正常运行。我希望你发现本书是一种很好的资源,并且可以节约时间。
致谢
  没有许多朋友的帮助,我不可能完成这本书。首先,我想要感谢我的技术编辑Joey Ebright 和Peter Himschoot ,他们在确保我的代码整洁、正确和切中要点方面做得非常出色。他们的架构洞察力和许多中肯的建议使得这本书更加完美。我还想要感谢我的编辑Christopher Cleveland 和Jeff Riley ,他们对本书的结构和流程提供了有价值的建议。最后,我想要感谢Joan Murray ,她给了我自信去接受这个挑战。我希望有机会在另一本书中再次和所有人一起合作。
    ——Bradley Irby, bradirby.com

封底文字

随着软件使用时间的增长,很多应用和系统迅速落后于现实应用世界,而且变得脆弱:难于修复、管理、使用和改进。作者结合多年软件再工程经验,并着重介绍了如何在不影响生产和服务的前提下,将新的架构和先进的特性集成到既有的关键业务系统的最佳实践,使.NET代码获得新生。本书使用一种循序渐进的方法,结合大量代码和案例,传授使系统变得更可靠、实用和易于维护的技术,为企业经济、便捷地解决系统老化问题提供方法指南。

覆盖内容包括:
 在不破坏软件的前提下,迁移旧版.NET软件到更加灵活、广泛和可维护的架构中;
 采用MVC、MVP和MVVM模式重构Web应用程序;
 提出正确的问题,以预测可能发生的重构问题;
 规划和组织再工程项目,在恰当的时间将合适的技术运用到每一个任务;
 采用创新的双重测试使得单元测试更加有效;
 应用依赖倒置打破紧耦合并促进开发和测试;
 利用源代码控制,缺陷跟踪和持续集成;
 在你未接触业务逻辑之前,通过清除旧版解决方案进行改善;
 建立坚实的开发基础结构以支持你的再工程项目;
 重构服务,涵盖知识库、域模型和命令调度程序的使用等高级技术;
 重构控制器/视图或视图模型/视图对。
对于所有开发人员、架构师和项目经理,以及那些想要了解再工程项目中团队所面临的独特挑战的大量非技术型管理人员和首席技术官来说,本书不容错过!

作者简介

(美)Bradley Irby 著:暂无简介

译者简介

张帆 翟林丰 译:暂无简介

译者序

科技日新月异,用户的需求也在不断提高和变化,而现有旧版系统常常已在其中投入了非常多的时间和成本,问题不断但弃之可惜。如何在不影响企业和用户的前提下,花最小的代价、最少的时间提升或改造旧版系统,使其重新稳定、高质量地满足用户需求呢?再工程无疑为困惑者指明了方向。和原书作者一样,我也是极力地推崇软件工程技术。与学校的书本教条不同,本书中的再工程,更多的是来自于行业的经验总结,带有实用主义的色彩。这也是我最终决定翻译本书的原因之一。另外,这本书适应了当下的需求,能为很多软件的改造提供指引和帮助,起到抛砖引玉的作用。如此,我也做了一件益事吧。
  过去的几年里,断断续续也翻译过一些科技文章,技术书籍等,但是那些工作,要么是比较零星,要么是半途夭折。能够像这本书一样,从头到尾,自始至终坚持翻译下来,自觉不易。浸淫国外文化多年,有的时候,读起来比较顺口的英文,也要花心思琢磨。另外,有些技术词汇,国内的和国外的叫法区别很大。为了更接近读者习惯,常翻字典和查阅科技文献。
翻译这本书的过程,也同时伴随了我自己第一个孩子的诞生。所以想把这本译作,当作是送给我亲爱的妻子祝骅和儿子文骏的一份礼物。人生贵在坚持。能够坚持,把一个事情做完整、做好,这就是一种幸福。希望我的家人能够体会到这种幸福。
  最后,还要感谢协助我参与本次翻译工作的翟林丰同学,以及中君科技的同事程欢、王丹婷和卢许骏等人。没有他们的配合,本书无法如期面世。
  谢谢帮助过和支持过我的人,也感谢自己的坚持和努力,更要感谢购买本书的读者。
张 帆

图书目录

译者序
前 言
第一部分 目标架构
第1章 实现面向服务的架构 2
1.1 面向服务的架构概览 2
1.2 理解标准化服务约定 3
1.3 理解耦合 8
1.4 理解服务抽象 10
1.5 设计可复用服务 13
1.6 理解服务自治和服务组合 13
1.7 理解服务的无状态性 13
1.8 一个服务示例 18
1.9 总结 19
第2章 理解应用程序架构 20
2.1 使用架构模式 20
2.2 架构模式概览 20
2.3 MVP、MVC和MVVM的区别 21
2.3.1 模型访问 22
2.3.2 视图模型 23
2.4 处理UI事件 28
2.5 模式如何工作 32
2.6 应该选择哪种模式 33
2.7 总结 34
第3章 单元测试 35
3.1 一个单元测试示例 35
3.2 创建单元测试 36
3.3 编写测试 38
3.4 检测异常 43
3.5 理解Assert的强大 46
3.6 单元测试与集成测试比较 46
3.7 使用InternalsVisibleTo属性 46
3.8 理解测试驱动开发 48
3.9 了解单元测试的更多内容 49
3.10 总结 49
第4章 理解依赖倒置原则 50
4.1 理解紧耦合 50
4.2 实现抽象工厂模式 56
4.3 引入接口 59
4.4 创建单元测试 62
4.5 理解服务定位 63
4.5.1 控制反转容器 63
4.5.2 服务定位器 66
4.5.3 一个真实的示例 68
4.5.4 按需服务属性 72
4.5.5 单元测试的优点 75
4.5.6 最后调整 75
4.6 使用依赖注入 78
4.7 为什么服务定位对再工程来说更好 82
4.8 总结 86
第5章 对单元测试使用测试替身 87
5.1 测试替身如何工作 87
5.2 测试替身可以满足什么需要 87
5.3 创建存根 90
5.4 创建模拟 94
5.4.1 第二个模拟示例 97
5.4.2 第三个模拟示例 98
5.5 使用模拟系统服务 99
5.6 了解测试替身的更多内容 101
5.7 总结 101
第二部分 再工程
第6章 回顾最初的解决方案 104
6.1 分析代码 104
6.1.1 基础架构 105
6.1.2 代码结构 105
6.1.3 数据库访问 106
6.1.4 数据结构 106
6.1.5 外部接口 106
6.1.6 应用程序控件与窗体控件 107
6.2 分析一般代码结构 107
6.3 管理语言迁移 108
6.4 删除死代码 108
6.5 使用全局变量 109
6.6 适度代码转换 111
6.7 使用自动化代码转换实用工具 112
6.8 使用数据访问技术 113
6.8.1 侦测数据模型 113
6.8.2 侦测数据访问模式 115
6.9 总结 115
第7章 项目规划 116
7.1 管理期望 116
7.2 创建再工程团队 116
7.3 识别开发工具和生成过程 117
7.3.1 引入源代码管理 117
7.3.2 引入缺陷跟踪 118
7.3.3 安装和使用持续集成服务器 118
7.4 清理旧版解决方案 119
7.5 建立基础 119
7.6 重构以使用基本服务 120
7.7 重构以使用高级服务 121
7.8 向利益相关者报告进展情况 121
7.9 管理沟通和培训 122
7.10 总结 122
第8章 识别开发工具和生成过程 123
8.1 使用源代码管理 123
8.1.1 源代码管理的类型 123
8.1.2 第一个流程示例:使用分布式系统 124
8.1.3 第二个流程示例:使用分布式系统 125
8.1.4 第三个流程示例:使用集中式系统 125
8.2 理解集中式系统和分布式系统的优缺点 125
8.2.1 使用别人的共享代码 126
8.2.2 与别人共享代码并审查更改 126
8.2.3 备份代码 126
8.2.4 管理签入频率 126
8.2.5 管理合并冲突 127
8.2.6 管理控制 127
8.2.7 优缺点的最后说明 127
8.3 评估主机托管服务 127
8.3.1 使用Apache Subversion 128
8.3.2 使用微软的团队基础服务器 128
8.3.3 使用Git 129
8.4 管理功能和缺陷 129
8.4.1 管理自定义工作流 129
8.4.2 管理敏捷开发 130
8.4.3 管理报告 130
8.5 使用持续集成服务器和生成服务器 130
8.6 使用Visual Studio 2010开发工具 131
8.6.1 Visual Studio的重构工具 131
8.6.2 第三方重构工具 132
8.7 总结 133
第9章 清理旧版解决方案 134
9.1 组织文件系统 134
9.2 项目结构化 135
9.3 确定项目类别 136
9.4 理解项目类型 137
9.4.1 应用程序无关项目 137
9.4.2 通用UI项目 137
9.4.3 模型无关项目 138
9.4.4 模型特定项目 138
9.5 再工程项目建议 138
9.5.1 常量 138
9.5.2 数据传输对象项目 139
9.5.3 接口 140
9.5.4 服务 140
9.5.5 域模型项目 141
9.5.6 Repository项目 141
9.5.7 控制器、视图模型和表示器 142
9.6 重构解决方案结构 142
9.6.1 去除不必要的Using语句 142
9.6.2 分离单元测试和集成测试 143
9.6.3 将类移动到合适的项目 143
9.6.4 将快捷方式移动到库 144
9.7 影响逻辑的重构 144
9.7.1 将初始化逻辑移动到构造器内 145
9.7.2 用卫语句代替嵌套的if语句 146
9.7.3 去除对实体类构造器的访问 150
9.8 总结 150
第10章 建立基础 151
10.1 添加新项目 151
10.2 使用Prism、Unity和Enterprise Library 版本 151
10.3 修改外壳程序 154
10.3.1 创建IBaseView 154
10.3.2 修改当前外壳程序 155
10.3.3 添加一个外壳程序控制器 156
10.4 创建服务定位器 157
10.5 建立Bootstrapper类 159
10.5.1 创建Winforms引导程序 159
10.5.2 更新Winforms Program类 161
10.5.3 创建一个WPF应用程序和引导程序 163
10.5.4 使用替代引导程序的配置 166
10.6 总结 168
第11章 服务的基本重构 169
11.1 使用DialogService 169
11.1.1 单元测试 173
11.1.2 重构DialogService 178
11.1.3 添加单元测试 179
11.2 使用LogWriterService 179
11.3 跟踪会话信息 184
11.4 以SOA方式访问资源 186
11.5 使用消息聚合器 190
11.6 转换静态类 194
11.7 重构静态类 194
11.8 总结 195
第12章 服务的高级重构 196
12.1 使用知识库模式 196
12.1.1 用域模型创建知识库 203
12.1.2 再工程知识库的方法 207
12.1.3 转换现有代码以使用域模型 207
12.1.4 向域模型中添加数据验证 208
12.1.5 再工程域模型以使用验证 212
12.2 使用通用对象管理器 212
12.3 用命令调度服务简化复杂代码 217
12.4 总结 225
第13章 重构为控制器 226
13.1 使用旧版方法创建窗体 226
13.2 准备视图 229
13.3 引入控制器 230
13.4 优化控制器 231
13.5 总结 233
附录 用Visual Studio 2012 再工程.NET项目 234

教学资源推荐
作者: Frank L. Friedman;Elliot B. Koffman
作者: 刘建舟 徐承志 陈荆亮 吴奕 编著 邵雄凯 主审
作者: 郭文夷 等编著
作者: (美)Maurice Herlihy 布朗大学 Nir Shavit 麻省理工学院 著
参考读物推荐
作者: 程墨 编著
作者: 陈营辉 赵海波
作者: (美)Charles Petzold
作者: 彭成寒 编著