幽城幻剑录结局动画:《代码大全2》-程序员心目中的编程圣经

来源:百度文库 编辑:偶看新闻 时间:2024/04/27 17:09:46

代码大全(第二版)CODE COMPLETE(Second Edition)
出版社:博文视点
原出版社:Microsoft Press
作者:[美]Steve McConnell
[ 预 定 ]
可预览样章:第一章第五章
内容简介
代码大全(第二版)是著名IT畅销书作者Steve McConnell十一年前的经典著作的全新演绎:第二版不是第一版的简单修订增补,而是完全进行了重写;增加了很多与时俱进的内容。这也是一本完整的软件构建手册,涵盖了软件构建过程中的所有细节。它从软件质量和编程思想等方面论述了软件构建的各个问题,并详细论述了紧跟潮流的新技术、高屋建瓴的观点、通用的概念,还含有丰富而典型的程序示例。本书中所论述的技术不仅填补 了初级与高级编程技术之间的空白,而且也为程序员们提供了一个有关编程技巧的信息来源。本书对经验丰富的程序员、技术带头人、自学的程序员及几乎不懂太多编程技巧的学生们都是大有裨益的。可以说,无论你是什么背景,阅读本书都会让你在更短的时间内、更容易地写出更好的程序。
前 言
普通的软件工程实践与最优秀的软件实践差距巨大——多半比其他工程学科中的这种差距都要大。因此传播优秀实践经验的工具是十分重要的。
——Fred Brooks
我写这本书的首要目的,就是希望缩小本行业中一般商业实践与大师级人物及专家们之间的知识差距。许多强大的编程技术在被编程领域的大众接触之前,都已在学术论文和期刊里尘封了多年。
虽然近年来前卫的软件开发实践迅速发展,但普通的实践手段并没有太大变化。很多程序的开发仍然是漏洞百出、迟于交付并且超出预算,还有很多根本就无法满足用户的需求。软件业界以及学术界的研究人员们已经发现了不少行之有效的实践经验,足以解决自20世纪70年代以来编程领域中日益蔓延的大多数问题。可是这些实践经验很少在高度专业化的技术期刊之外对外发表,所以时至今日大多数编程的机构和组织还没能用上这些技术。有研究表明,一项研发成果从其诞生之日起,到进入商业实践阶段,通常要经历5到15年的时间甚至更长(Raghavan和Chand 1989;Rogers 1995;Parnas 1999)。这本手册就是想缩短这一漫长的过程,让那些关键性的研发成果现在就能为更多编程人员所用。
Who Should Read This Book
谁应当阅读本书
本书中所汇集的研究成果和编程经验,将帮助你创建更高质量的软件,使你能更快速地进行开发,遇到的问题更少。本书将帮你弄明白过去为什么会遇到那些问题,并告诉你如何在将来避免它们。这里所描述的编程实践将帮助你把控更大型的项目,还能在项目的需求发生变动时帮助你成功地维护并修改已经开发出来的软件。
Experienced Programmers
经验丰富的程序员
对于经验丰富的程序员而言,本书正是他们想要的一本翔实、易用的软件开发指南。本书关注的是“构建(construction)”,即整个软件生命周期中最为人熟知的部分;本书把强大的软件开发技术写得让自学的程序员和参加过正规训练的程序员都能读懂。
Technical Leads
技术领导
许多技术领导(或者说是技术带头人)都曾在他们的团队中使用《代码大全》(第一版)培训经验不足的程序员。当然,本书也可以用来填补你自己的知识缺陷。如果你是一位经验丰富的程序员,你不一定会同意我给出的所有结论(如果不是这样,我倒会觉得奇怪)。但如果你阅读本书并思索其中的每一个问题之后,那么几乎不会有人再能提出什么你未曾思考过的软件构建方面的问题了。
Self-Taught Programmers
自学的程序员
如果你没有受过太多的正规训练,本书正是你的良伴。每年约有50000个新手进入这一专业领域(BLS 2004, Hecker 2004),但每年却只有35000个人获得与软件相关的学位(NCES 2002)。从这些数据中我们可以很快得出一个结论——很多程序员并没有接受过软件开发方面的正规教育。在许多新兴的专业人员社群中都可以看到自学的编程人员——工程师、会计师、科学家、教师以及小公司的老板们;编程序是他们工作的一部分,但他们并不一定把自己看作是程序员。无论你在编程方面受过何种程度的教育,本手册都会让你能对各种行之有效的编程实践有深入的了解。
Students
学生
与有经验但缺乏正规培训的程序员对应的,是那些刚刚毕业的大学生。新近毕业的学生大多拥有丰富的理论知识,但却缺乏创建产品级的程序(production programs)的实践技术。关于编写优秀代码的实践知识,就像部落里祭祀仪式上的舞蹈一样,只能慢慢地从软件架构师、项目负责人、分析师以及更有经验的程序员那里传承下来。更多的时候,这些知识就是程序员个人反复的尝试和犯错后的结晶。本书则是这些缓慢、传统的智慧传承方式的一种替代方案,它汇集了以往只能从他人经验中猎取和收集的大量实用的经验技巧和有效的开发策略。对于那些正在从学术环境转向专业环境的学生来说,这是一本必备的读物。
Where Else Can You Find This Information
还能从何处找到这些信息
本书综合整理了来自四面八方的多种软件构建技术。这些技术是软件构建领域长年累月积聚下来的智慧财富,它们不仅分散,而且其中大部分素材常年散落于纸面之外(Hildebrand 1989,McConnell 1997a)。其实,内行的程序员们所用的那些强大有效的编程技术并不神秘。但是这些内行人士面对手头日复一日紧张冲刺的项目,几乎没有谁花些时间和大家分享他们所学到的知识和技能。因此,程序员们可能很难找到很好的关于编程的信息来源。
而本书所描述的技术则填补了入门图书和高级编程图书之间的空白。当你读过了《Java编程入门》、《高级Java编程》和《高高级Java编程》之后,如果你还想学更多的编程知识,那还能读点什么呢?你可以阅读Intel或Motorola的硬件参考手册,阅读Microsoft Windows或Linux操作系统的函数手册,甚至是去阅读讲另外一门编程语言的书籍——你确实无法在一个缺乏这种详细参考资料的环境中使用语言或者程序。但本书是为数不多的探究编程本质的书籍之一。无论你在何种环境下、用何种语言编写程序,书中某些最有益处的编程技术都能派上用场。其他的书一般都忽略了这些实践知识,而这也正是本书专注于这些知识的原因。
本书中的信息是从许多来源中提炼出来的,如下图所示。想完全获得在本书中看到的这些信息的另外途径只有一条,那就是通读堆积如山的书籍和成百上千本技术期刊,还得再加上大量的实际经验。即便你把这些事情都做到了,本书仍然会对你很有益处,因为它把所有这些资料都集于一处,便于查阅。

Key Benefits of This Handbook
阅读本书的收益
无论你是何种背景,本书都能助你在更短的时间内写出更棒的程序,还不会那么头疼。
全面的软件构建参考 本书讨论了软件构建活动的方方面面,比如说软件的质量,还有编程的思维方式。它还会深入阐述构建活动中的重要细节,如创建一个类的步骤,使用数据和控制结构时的各种事项,还有调试、重构、代码调优的技术与策略等。你无须逐页通读所有主题。本书写得让你很容易就能找到感兴趣的特定话题。
随时备用的检查单 本书包括了大量的检查单(checklist),你可以用它来评估软件架构、设计方法、类和子程序的质量、变量命名、控制结构、代码格式、测试用例等等。
与时俱进的信息 本书介绍了一些当今最为入时的技术,其中有许多还未被广泛采用。正因为本书撷取了实践与研究两者的精髓,它所介绍的这些技术将经久不衰,受用多年。
以更广的视角检视软件开发 本书将给你一个机会,让你凌驾于日复一日、忙于救火的混乱场面之上,看看到底什么是可行的,而什么又是不可行的。实践中的程序员们很少有时间去阅读数以百计的书籍与期刊,而本手册萃取了其中的精华。本书所汇集的理论研究与实践经验将活跃你的思维,激励你对自己项目的思考,使你的行动更有策略,避免反复陷入完全一样的战斗。
绝不注水 有些软件书籍,其中精髓部分的净重也就1克,却注入了重达10克的水分。本书则会公平地探讨每项技术的优劣。关于你自己项目的特定需求,你了解得要比任何人都清楚。因此本书仅是给你公正客观的信息,让你能够具体情况具体分析,做出正确的决策。
有关概念适用于大多数常见的语言 本书中介绍的技术使你可以更好地利用你的编程语言,无论是C++、C#、Java、Visual Basic,还是其他类似语言。
丰富的代码示例 本书中收集了近500个用于展现优、劣代码之差异的示例。之所以给出这么多示例也是出于个人的偏好。因为从示例中我最能学到东西,我想其他程序员也该可以通过这种方式学得更好吧。
这些示例是用了多种不同的语言所写成,因为学习并掌握不止一门语言通常是专业程序员职业生涯中的分水岭。一旦一名程序员意识到编程原则是超越特定语言语法的东西时,通往能够实质地改善编程质量并提高工作效率的知识的大门也就向他敞开了。
为了避免以多种语言写成的例子成为读者的负担,我会尽量避免使用各语言中那些深奥的特性——除非当时就是需要探讨它。为了弄懂一个代码片段要表达的问题,你无须完全理解所有的细枝末节。如果你集中关注示例所展示的问题,那么无论它是用什么语言写成的,你都能读懂。为让你更容易理解这些示例,我还给其中的关键部分加了注解。
引用其他信息来源 本书汇集了为数众多关于软件构建方面的可用信息,但这并不算完。在本书所有的章节中,“更多资源”一节都会介绍其他一些书籍和文章,你希望进一步深入了解感兴趣的话题时可以阅读它们。
配套网站 在本书的配套网站cc2e.com上会提供更新的检查单、参考书目、杂志文章、网页链接等内容。要访问《代码大全》(第二版)中的相关信息,请如本段文字左侧所示,在浏览器中输入“cc2e.com/”,后跟一个四位阿拉伯数字即可。这样的网址参考链接在本书中会有很多。
cc2e.com/1234
Why This Handbook Was Written
为什么要写这本手册
在软件工程界,人们都清楚地认识到,应该把软件开发中行之有效的实践知识归纳、编撰成一本开发手册。计算机科学与技术委员会(Computer Science and Technology Board)的一份报告指出,要想大幅提高软件开发的质量和工作效率,需要把已知的行之有效的软件开发实践知识归纳、统一并广为传播(CSTB 1990, McConnell 1997a)。该委员会还指出,传播这些知识的策略应建立在软件工程手册这个概念的基础之上。
The Topic of Construction Has Been Neglected
软件构建的话题常被忽视
曾几何时,软件开发和编写代码被认为是同一件事情。但随着软件开发周期中的各个活动被人们逐渐认识,该领域中一些最棒的头头脑脑们就开始花更多时间去分析和争论诸如项目管理方法、需求、设计、测试等问题了。在这场学习研究新兴领域的浪潮中,代码构建这个与软件开发骨肉相连的环节反而被忽视了。
关于软件构建的讨论之所以步履蹒跚,也是因为有人认为,如果将构建活动视作软件开发中的一项特定活动,就暗示着也必须把它视作其中一个特定阶段。然而实际上,软件开发中的各项活动和各个阶段无须以特定的关系一一对应起来;而且无论其他的软件活动是分阶段(phase)进行、还是迭代式(interation)进行,或者以某种其他方式进行,都不妨碍我们探讨“构建活动”。
Construction Is Important
构建活动是重要的
构建活动被学者和作者所忽略的另一个原因是源于一个错误的观念,他们认为与其他软件开发活动相比,构建是一个相对机械化的过程,并没有太多可改进的机会。然而事实并非如此。
“代码构建”一般占据了小型项目65%的工作量,而在中型项目上也达到了50%。同时,“构建”也要为小型项目中75%的错误负责,在中到大型项目上这一比例为50%到75%。任何一个要为50%到75%的错误负责的活动环节显然都是应该加以改善的。(第27章中对这些统计数据有更多详细的探讨。)
也有一些评论家指出,虽然构建阶段发生的错误在所有错误中占有很大的比例,但修正这些错误的代价往往比“修正那些由于需求和架构所导致的错误”要低很多,这也就暗示着构建活动因此不那么重要。诚然,修正由构建活动所导致的错误的代价比较低这一说法是正确的,但它也引起了误导——因为如果不修正这些错误,代价反而会高得令人难以置信。研究人员发现,软件中一些代价最为昂贵的错误,其罪魁祸首常常是一些小范围的代码错误,其代价甚至可以飙至上亿美元的程度(Weinberg 1983,SEN 1990)。可以用较低代价修正的错误,并不意味着这些错误的修正不重要。
人们忽视构建活动的另一种原因则颇具讽刺意味——就因为它是软件开发中唯一一项肯定能完成的活动。对于需求,人们可以自以为是而不去潜心分析;对于架构,人们可以偷工减料而不去精心设计;对于测试,人们可以短斤少两甚至跳过不做,而不去整体计划并付诸实施。但只要写出来的是程序,总归要进行构建活动,这也说明,只要改进软件构建这一环节,就一定对软件开发实践有好处。
No Comparable Book Is Available
没有可媲美的同类书籍
当艺术评论家聚在一起的时候,他们谈论的都是关于版式、结构以及意蕴之类的话题;而当真正的艺术家聚在一起的时候,他们谈论的则是到哪儿才能买到更便宜的松节油。
—Pable Picasso(毕加索)
既然看到构建活动有着如此清晰的重要性,我曾相信,当我构思此书时已有人写过关于有效的软件构建实践的书籍了。对这样一本介绍如何有效编程的书籍的需求看上去很明显,但是我却只找到很少几本关于软件构建这一题材的书,而且那些书也仅是涉及到这个话题的一部分罢了。有些书写于15年前,还是和一些深奥的语言——如ALGOL、PL/I、Ratfor以及Smalltalk等——紧密相关的。有些则是出自并不实际编写产品代码的教授之手。教授们写出来的技术内容对于学生们的项目而言还行得通,但他们通常不知道如何在完整规模的开发环境中施展这些技术;还有些书是为了宣传作者最新钟情的某种方法论,却忽略了那些被时间反复证明是行之有效的成熟实践技术的巨大宝库。
简而言之,我没有找到哪怕是一本试图归纳总结来自专家经验、业界研究以及学术成果的实践编程技术的书籍。关于这个话题的讨论要能和现今的编程语言、面向对象编程技术以及前沿的开发实践紧密结合。很明显需要什么人写出这样一本书来,而他必须了解当今的理论发展水平,同时也编写过足够多的能反映实践状况的产品级代码。我把本书构思成关于代码构建活动的完整探讨——一个程序员给其他程序员写的书。
 
Author Note
作者注
欢迎您对本书中所探讨的话题进行质询,例如您的勘误报告,或其他相关的内容。请发邮件与我联系,我的邮箱是stevemmc@construx.com,也可以访问我的网站:www.SteveMcConnell.com。
Bellevue, Washington
Memorial Day, 2004
Microsoft Learning Technical Support
Every effort has been made to ensure the accuracy of this book. Microsoft Press provides corrections for books through the World Wide Web at the following address:
http://www.microsoft.com/learning/support/
To connect directly to the Microsoft Knowledge Base and enter a query regarding a question or issue that you may have, go to:
http://www.microsoft.com/learning/support/search.asp
If you have comments, questions, or ideas regarding this book, please send them to Microsoft Press using either of the following methods:
Postal Mail:
Microsoft Press
Attn: Code Complete 2E Editor
One Microsoft Way
Redmond, WA 98052-6399
E-mail:
mspinput@microsoft.com
第1章 欢迎进入软件构建的世界
1.1 什么是软件构建
1.2 软件构建为何如此重要
1.3 如何阅读本书
关键点
第2章 用隐喻来更充分地理解软件开发
2.1 隐喻的重要性
2.2 如何使用软件隐喻
2.3 常见的软件隐喻
软件中的书法:写作代码
软件的耕作法:培植系统
软件的牡蛎养殖观点:系统生长
软件构建:建造软件
应用软件技术:智慧工具箱
组合各个隐喻
更多资源
关键点
第3章 三思而后行:前期准备
3.1 前期准备的重要性
前期准备适用于现代软件项目吗
准备不周全的诱因
关于开始构建之前要做前期准备的绝对有力且简明的论据
3.2 辨明你所从事的软件的类型
迭代开发法对前期准备的影响
在序列式开发法和迭代式开发法之间做出选择
3.3 问题定义的先决条件
3.4 需求的先决条件
为什么要有正式的需求
稳定需求的神话
在构建期间处理需求变更
3.5 架构的先决条件
架构的典型组成部分
3.6 花费在前期准备上的时间长度
更多资源
关键点
第4章 关键的“构建”决策
4.1 选择编程语言
语言描述
4.2 编程约定
4.3 你在技术浪潮中的位置
“深入一种语言去编程”的例子
4.4 选择主要的构建实践方法
关键点
第5章 软件构建中的设计
5.1 设计中的挑战
设计是一个险恶的问题
设计是个了无章法的过程(即使它能得出清爽的成果)
设计就是确定取舍和调整顺序的过程
设计受到诸多限制
设计是不确定的
设计是一个启发式过程
设计是自然而然形成的
5.2 关键的设计概念
软件的首要技术任务:管理复杂度
理想的设计特征
设计的层次
5.3 设计构造块:启发式方法
寻找现实世界中的对象
形成一致的抽象
封装实现细节
当继承能简化设计时就继承
隐藏秘密(信息隐藏)
找出容易改变的区域
保持松散耦合
查阅常用的设计模式
其他的启发式方法
关于设计启发的总结*****
使用启发式方法的原则
5.4 设计实践
迭代
分而治之
自上而下和自下而上的设计方法
建立试验性原型
合作设计
要做多少设计才够?
记录你的设计成果
5.5 对流行的设计方法的评论
更多资源
软件设计,一般性问题
软件设计理论
设计模式
广义的设计
标准
关键点
第6章 可以工作的类
6.1 类的基础:抽象数据类型
需要用到ADT的例子
使用ADT的益处
更多的ADT示例
在非面向对象环境中用ADT处理多份数据实例
ADT和类
6.2 良好的类接口
好的抽象
良好的封装
6.3 有关设计和实现的问题
包含(“有一个……”的关系)
继承(“是一个……”关系)
成员函数和数据成员
构造函数
6.4 创建类的原因
应该避免的类
总结:创建类的理由
与具体编程语言相关的问题
6.6 超越类:包
更多资源
关键点
第7章 高质量的子程序
7.1 创建子程序的正当理由
似乎过于简单而没必要写成子程序的操作
总结:创建子程序的理由
7.2 在子程序层上设计
7.3 好的子程序名字
7.4 子程序可以写多长
7.5 如何使用子程序参数
7.6 使用函数时要特别考虑的问题
什么时候使用函数,什么时候使用过程
设置函数的返回值
7.7 宏子程序和内联子程序
宏子程序在使用上的限制
内联子程序
关键点
第8章 防范式编程
8.1 保护程序免遭无效输入数据的破坏
8.2 断言
建立自己的断言机制
使用断言的指导建议
8.3 错误处理技术
健壮性与正确性
高层次设计对错误处理方式的影响
8.4 异常
8.5 隔离程序以免遭由错误造成的损害
隔离区与断言的关系
8.6 辅助调试代码
不要自动地把产品版本的限制强加于开发版本之上
尽早引入辅助调试的手段
采用冒进式编程
计划移除调试辅助代码
8.7 确定在产品代码中该保留多少防范式代码
8.8 防范式编程时保持防范
其他资源
关键点
第9章 伪代码编程过程
9.1 创建类和子程序的步骤概述
创建一个类的步骤
创建子程序的步骤
9.2 伪代码
9.3 通过伪代码编程过程创建子程序
设计子程序
编写子程序
检查代码
收尾工作
根据需要重复上述步骤
9.4 伪代码编程过程之外的其他方案
关键点
第10章 使用变量的一般事项
10.1 数据认知
数据认知测试
有关数据类型的其他资源
10.2 轻松掌握变量定义
隐式声明
10.3 变量初始化原则
10.4 作用域
使变量引用局部化
尽可能缩短变量的“存活”时间
减小作用域的一般原则
有关缩小变量作用域的说明
10.5 持续性
10.6 绑定时间
10.7 数据类型和控制结构之间的关系
10.8 为变量指定单一用途
关键点
第11章 变量名的力量
11.1 选择好变量名的注意事项
最重要的命名注意事项
以问题为导向
最适当的名字长度
变量名字的效果范围
变量名字中的计算值限定词
变量名字中的常用反义词
11.2 为特定类型的数据命名
为循环索引命名
为状态变量命名
为临时变量命名
为布尔变量命名
为枚举类型命名
为常量命名
11.3 命名规则的力量
为什么要有规则?
何时采用命名规则
正式程度
11.4 非正式命名规则
语言无关规则的指导原则
语言相关规则的指导原则
混合语言编程的注意事项
命名规则示例
11.5 标准前缀
用户自定义类型缩写
语义前缀
标准前缀的优点
11.6 创建具备可读性的短名称
一般的缩写指导原则
语音缩写
有关缩写的评论
11.7 应该避免的名称
关键点
第12章 基本数据类型
12.1 使用数的普遍规则
12.2 整数
12.3 浮点数
12.4 字符和字符串
C中的字符串
12.5 布尔变量
12.6 枚举类型
如果你的语言里没有枚举类型
12.7 命名常量
12.8 数组
12.9 创建你自己的类型(类型别名)
为什么创建自己的类型的示例是用Pascal和Ada写的?
创建自定义数据类型的指导原则
关键点
第13章 不常见的数据类型
13.1 结构
13.2 指针
用来理解指针的例子
使用指针的一般技巧
C++指针
C指针
13.3 全局数据
与全局数据有关的常见问题
使用全局数据的理由
只有万不得已时才使用全局数据
用访问子程序来取代全局数据
如何降低使用全局数据的风险
其他资源
关键点
第14章 组织直线型代码
14.1 必须有明确顺序的语句
14.2 顺序无关的语句
使代码易于自上而下的阅读
把相关的语句组织在一起
关键点
第15章 使用条件语句
15.1 if语句
简单if-then语句
if-then-else语句串
15.2 case语句
为case选择最有效的排序
使用case语句的提示
关键点
第16章 控制循环
16.1 选择循环的种类
什么时候使用while循环
什么时候用带退出的循环
何时使用for循环
何时使用foreach循环
16.2 循环控制
进入循环
处理好循环体
退出循环
检查端点
使用循环变量
循环应该有多长
16.3 轻松创建循环——由内而外
16.4 循环和数组的关系
关键点
第17章 不常见的控制结构
17.1 子程序中的多个返回
17.2 递归
递归的例子
使用递归的技巧
17.3 goto
反对goto的论点
支持goto的观点
关于goto的虚假辩论
错误处理和goto
goto和在else子句中的共享代码
goto使用原则总结
17.4 对不常见控制结构的看法
其他资源
关键点
第18章 表驱动方法
18.1 表驱动方法使用总则
使用表驱动方法的两个问题
18.2 直接访问表
示例:一个月中的天数(Days-in-Month)
示例:保险费率
例子:灵活的消息格式(Flexible-Message-Format)
构造查询键值
18.3 索引表访问(Indexed Access Tables)
18.4 阶梯访问表
18.5 表查询的其他示例
关键点
第19章 一般控制问题
19.1 布尔表达式
用true和false做布尔判断
简化复杂的表达式
编写肯定形式的布尔表达式
用括号使布尔表达式更清晰
理解布尔表达式是如何求值的
按照数轴的顺序编写数值表达式
与0比较的指导原则
布尔表达式的常见问题
19.2 复合语句(块)
19.3 空语句
19.4 驯服危险的深层嵌套
对减少嵌套层次的技术的总结
19.5 编程基础:结构化编程
结构化编程的三个组成部分
19.6 控制结构与复杂度
复杂度的重要性
降低复杂度的一般原则
其它类型的复杂度
关键点
第20章 软件质量概述
20.1 软件质量的特性
20.2 改善软件质量的技术
开发过程
设置目标
20.3 不同质量保障技术的相对效能
缺陷检测率
找出缺陷的成本
修正缺陷的成本
20.4 什么时候进行质量保证工作
20.5 软件质量的普遍原理
推荐读物
相关标准
关键点
第21章 协同构造
21.1 协同开发实践概要
协同构造是其他质量保证技术的补充
协同构造有利于传授公司文化以及编程专业知识
集体所有权适用于所有形式的协同构造
在构造前后都应保持协作
21.2 结对编程
成功运用结对编程的关键
结对编程的好处
21.3 正式检查
你期望检查能够带来什么结果
检查中的人员角色
检查的一般步骤
检查中的自尊心
检查和代码大全
检查总结
21.4 其他类型的协同开发实践
走查
代码阅读
大型演示
协同构造技术的比较
参考资料
结对编程
检查
相关标准
关键点
第22章 开发者测试
22.1 开发者测试在软件质量中的角色.. 500
构造中测试
22.2 推荐的开发者测试方法
先测试还是后测试
开发者测试的局限性
22.3 测试技巧锦囊
不完整的测试
结构化的基础测试
数据流测试
等价类划分
猜测错误
边界值分析
几类坏数据
几类好数据
采用容易手工检查的测试用例
22.4 典型错误
哪些类包含最多的错误?
错误的分类
不完善的构造过程引发错误所占的比例
你期望能发现多少错误
测试本身的错误
22.5 测试支持工具
为测试各个类构造脚手架
Diff工具
测试数据生成器
覆盖率监视器
数据记录器/日志记录器
符号调试工具
系统干扰器
错误数据库
22.6 改善测试过程
有计划的测试
重新测试(回归测试)
自动化测试
22.7 保留测试记录
个人测试记录
推荐读物
测试
测试脚手架
测试优先的开发
相关标准
关键点
第23章 调 试
23.1 调试概述
调试在软件质量中所扮演的角色
调试效率的巨大差异
让你有所收获的缺陷
一种效率低下的调试方法
23.2 寻找缺陷
科学的调试方法
寻找缺陷的一些小建议
语法错误
23.3 修正缺陷
23.4 调试中的心理因素
心理取向如何导致调试时的盲目
“心理距离”在调试中的作用
23.5 调试工具——明显的和不那么明显的.. 557
源代码比较工具
编译器的警告消息
扩展的语法和逻辑检查
执行性能分析器
测试框架
调试器
其它资源
关键点
第24章 重构
24.1 软件进化的类型
软件进化的哲学
24.2 重构简介
重构的理由
拒绝重构的理由
24.3 特定的重构
数据级的重构
语句级的重构
子程序级重构
类实现的重构
类接口的重构
系统级重构
24.4 安全的重构
不宜重构的情况
24.5 重构策略
推荐读物.. 585
关键点.. 585
第25章 代码调整策略
25.1 性能概述
质量特性和性能
性能和代码调整
25.2 代码调整简介
Pareto法则
一些无稽之谈
何时调整代码
编译器优化
25.3 蜜糖和哥斯拉
常见的低效率之源
常见操作的相对效率
25.4 性能测量
性能测量应当精确
25.5 反复调整
25.6 代码调整方法总结
推荐读物
算法和数据类型
关键点
第26章 代码调整方法
26.1 逻辑
在知道答案后停止判断
按照出现频率来调整判断顺序
相似逻辑结构之间的性能比较
用查找表替代复杂表达式
使用惰性求值
26.2 循环
将判断外提(Unswitching)
合并循环
展开
尽可能减少再循环内部做的工作
哨兵值
把最忙的循环放在最内层
削减强度
26.3 数据变换
使用整型数而不是浮点数
数组维度尽可能少
尽可能减少数组引用
使用辅助索引
使用缓存机制
26.4 表达式
利用代数恒等式
削弱运算强度
编译时初始化
小心系统函数
使用正确的常量类型
预先算出结果
删除公共子表达式
26.5 子程序
将函数重写为内联
26.6 用低级语言重写代码
26.7 变得越多,事情反而更没变
推荐读物
关键点
第27章 程序规模对“构筑”的影响
27.1 交流和规模
27.2 项目规模的范围
27.3 项目规模对错误的影响
27.4 项目规模对生产率的影响
27.5 项目规模对开发活动的影响
活动比例和项目规模
程序、产品、系统和系统产品
方法论和规模
额外资源
关键点
第28章 管理“构筑”
28.1 鼓励良好的编码实践
设定标准的考虑事项
鼓励良好的编码实践的技术
本书的角色
28.2 配置管理
什么是配置管理?
需求变更和设计变更
软件代码变更
工具版本
机器配置
备份计划
有关配置管理的额外资源
28.3 评估“构筑”进度表
评估的方法
评估“构筑”的工作量
对进度的影响
评估与控制
如果你落后了该怎么办
有关软件评估的额外资源
28.4 度量
有关软件度量的额外资源
28.5 把程序员当人看
程序员们怎样花费时间?
性能差异与质量差异
信仰问题
物理环境
有关“把程序员当人看”的额外资源
28.6 管理你的管理者
有关管理构造的额外资源
相关标准
关键点
第29章 集成
29.1 集成方式的重要性
29.2 集成频率——阶段式集成还是增量集成
阶段式集成
增量集成
增量集成的益处
29.3 增量集成的策略
自顶向下集成
自底向上集成
三明治集成
风险导向的集成
功能导向的集成
T-型集成
集成方法小结
29.4 Daily Build与冒烟测试
哪种项目能用daily build过程?
持续集成
额外资源
关键点
第30章 编程工具
30.1 设计工具
30.2 源代码工具
编辑
分析代码质量
重构源代码
Version Control
数据词典
30.3 可执行码工具
产生目标码
除错
测试
代码微调
30.4 工具导向的环境
30.5 打造你自己的编程工具
项目特有的工具
脚本
30.6 工具幻境
额外资源
关键点
第31章 布局与风格
31.1 基本原则
布局的极端情况
格式化的基本原理
人和计算机对程序的解读
好布局有什么用?
把布局作为一种信仰
良好布局的目标
31.2 布局技术
空白区
括号
31.3 布局风格
纯块结构
模仿纯块结构
使用begin - end对(大括号)指定块边界
行尾布局
哪种风格最优?
31.4 控制结构的布局
格式化控制结构块的要点
其他考虑
31.5 单条语句的布局
语句长度
用空格使语句显得清楚
格式化后续行
每行仅写一条语句
数据声明的布局
31.6 注释的布局
31.7 子程序的布局
31.8 类的布局
类接口的布局
类实现的布局
文件和程序布局
更多资源
关键点
第32章 自说明代码
32.1 外部文档
32.2 编程风格作文档
32.3 注释或不注释
32.4 高效注释之关键
注释种类
高效注释
最佳注释量
32.5 注释技术
注释单行
注释代码段
注释数据声明
注释控制结构
注释子程序
注释类、文件和程序
32.6 IEEE标准
软件质量保证标准
更多资源
关键点
第33章 个人性格
33.1 个人性格是否和本书话题无关
33.2 聪明和谦虚
33.3 求知欲
33.4 诚实
33.5 交流与合作
33.6 创造力和纪律
33.7 偷懒
33.8 不像你想象中那样起作用的性格
矜持
经验
编程狂人
33.9 习惯
更多资源
关键点
第34章 软件开发艺术的有关问题
34.1 克服复杂性
34.2 精选编程过程
34.3 为人写程序,其次才是为机器
34.4 以所用语言编程,但思路不受其约束.. 843
34.5 借助规范集中注意力
34.6 基于问题域编程
将程序划分为不同层次的抽象
34.7 “当心落石”
34.8 反复,再反复
34.9 不要顽固不化
判断
折中主义
试验
关键点
第35章 何处有更多信息
35.1 关于软件创建的信息
35.2 创建之外的话题
综述资料
软件工程综览
其他注释过的参考书目
35.3 期刊
初级程序员杂志
高级程序员杂志
专题出版物
35.4 软件开发者的读书计划
入门级
熟练级
精通级
35.5 参加专业组织
译 序
点题
我很荣幸能够代表《代码大全》第2版的全体译者、审阅者作序。在这篇序中,我想先来说说这本书的名字。
一本书的名字理应是全书的点睛之笔。然而,当《代码大全》一书的第1版在1993年被学苑出版社引入国内并译为中文版本的时候,“Code Complete”被译为了“代码大全”——这实在是一个有趣的错误。
Code Complete到底是什么意思?我们不妨对比其他一些常见的说法:Mission Complete——“任务完成”(游戏中常见);Download Complete——“下载完成”(浏览器中常见)……那么,Code Complete不就是“编码完成”的意思吗?
据我了解,在一些现代软件工程中,“Code Complete”确实就是整个软件开发过程中的一个重要的里程碑(milestone),就如同大家可能更为熟悉的Beta、Final、Release Candidate(RC)以及Release-To-Manufacture(RTM)一样。在开发一个软件的过程中,到达这个里程碑就意味着,用于实现软件规格中所有功能的代码都已经编写完成了。当然,这里所谓的“完成”还只是在比较局部的颗粒度上而言。在这一里程碑之后,还需要进行系统级的代码集成与测试才能达到“产品完成”的程度。
用更通俗的话说,如果你是在建造一座大厦,“Code Complete”就相当于大厦封顶——虽然还不能立即入住,但该有的部件都有了;如果你是在烹饪一道大餐,“Code Complete”就相当于入盘、上桌之前的时刻,此时所有的主料、辅料都已备妥——但厨师还没来得及亲自品品味道并最终完成这道作品;如果你是乔迁新居,“Code Complete”时就相当于装修完毕了、家具买齐了,但一切还没有最终摆好的时候。
回到软件行业的环境中来说,在软件工程到达“Code Complete”这一里程碑之前的主要工作内容应该就是逐层地完成每一个部件——从一个个变量、一条条语句聚成一个个子程序、一个个类,再到一个个包、一个个子系统……让所有这些部件把软件规格中定义的所有功能特性加以实现。
这,才是《Code Complete》一书的主题所在——教会你为了到达“编码完成”这一重要里程碑所必需的所有软件构建技术。正是这样一本完整而实用的编码技术手册,在十余年之间影响了一代程序员,帮助他们用更少的时间写出更好的代码,也因此两度荣获《软件开发杂志》的震撼大奖(Jolt Award),成为了软件业经典图书中的代表。
本书把软件构建过程中的方方面面讲解得淋漓尽致,尤其是细微之处,更能够窥见作者深厚的编码功力和丰富的编码经验。从内容上讲,全书确实是关于软件构建技术的“大全”之作。如此说来,当初这么一个简单的主谓结构短语被误译为“代码大全”之后,却也被大多数业内人士所接受、认可甚至广为流传,还是有一定道理的。
当然了,在现代的集成开发环境(IDE)中,“Code Complete”还有另外一个意思,就是“补全代码”——一种根据代码的上下文自动把不完整的代码补充为完整的功能。如果有些人把这个意思认定为本书主题,那就实在是谬误至极了。比如这个网站:
http://www.cocw.net/mit/Chemical-Engineering/10-34Numerical-Methods-Applied-to-Chemical-EngineeringFall2001/-RelatedResources/
事实上,“代码大全”这四个字从它在十多年前被确定下来之时,就注定要和这本书一起成为经典的代名词,甚至成为一个品牌。鉴于“代码大全”的大名早已深深印在一代程序员的心中,最终我们决定在本书的第2版中继续沿用这一“恰如其分”的错误,也借此向原书第1版各位译者、修订者们的辛勤劳动表示我们的敬意。
译史
2001年4月份,一位网名Bear的朋友借助www.DelphiDevelopers.com网站组织了近100位朋友,在1993年学苑出版社译本的基础上,历时近6个月完成了电子修订版本。这也是目前大多数人所看到的该书第1版的最全面、完整的版本。
直到2004年,作者Steve McConnell把这本两次荣获《软件开发杂志》震撼大奖的经典之作全面翻新为第2版,它并不是对原书第1版的简单修订,而是填补了大量崭新的、与时俱进的实用内容。
在确定最终译稿的时候,我们已经把微软出版社业已公布的原书已知错误加以修正了。同时,在和原书作者确认并经过同意之后,我们也更正了原文中若干尚未发现的错误。
既然是一本专业书籍,字里行间肯定少不了专业的术语。而如何对这些术语进行翻译,则是一件重要的决策。我这些年来主要都是以阅读原版的英文读物为主,如果单纯以这样的背景来说,我倒是主张对某些术语保持其英语原貌为妥。如果保持英文原貌不雅(或不可接受)的话,那么我的主张是以读者可以理解原著要表达的意义为准。比如说,对“build”这一术语来说,应该怎么翻译才妥当呢?“请把整个程序重新建立一遍。”有多少人在日常工作中是这样说的呢?又有多少人能听得懂这样的说法呢?因此,build一词译为“建立”、“创建”就都不甚妥当,因为它无法让人正确、自然地理解原文所要表达的意思。
像这样的术语在书中数不胜数,对这些术语进行正确的处理实在是一大难题。为了能够确保本书按时、保质的出版,几位译者达成共识,不花更多时间过分地拘泥于词藻细节,而是尽可能保证全书整体的可读性。希望这一努力能够得到读者您的认同。
古人云:奇文共欣赏,疑义相与析。这本书内容十分实用,在文字运用上却十分灵活。几位译者的译文,虽称不上是什么奇文,但肯定少不了会有疑义。为此,我们效仿原书作者,在互联网上将其配套网站也全面本地化,并计划增加与读者互动的功能。所做这些,无不是希望读者能够真正从书中得到有益的知识,而不是仅仅停留在文字水平对译文进行批判。
感谢
杨哈达和郑毅帆两人完成了全书大部分章节的初译工作。随后,陈硕、汤凌和张菲和我一同对全书的剩余部分进行了翻译,并分别对全书各章文字进行修订和润色。最后,北京大学的裘宗燕教授(《程序设计语言——实践之路》的译者)在百忙之中审订了全书,裘老师严谨治学的态度和流畅优雅的文笔保证了全书的专业质量和文字水准。
特别要感谢博文视点的周筠老师,这也是我们的第一次合作。虽说是首次合作,周老师仍是给予我极大的信任。在我们遇到困难的时候,她又是无私的给我们鼓励和帮助。负责全书文字编辑工作的陈元玉女士也为本书的顺利出版做出了重要的贡献。
在此我代表所有为此书出版付出辛勤汗水的朋友们表示感谢,没有你们的努力就不会有这本书的面世。
错误在所难免,也请广大读者用积极的态度来看待,并在网上与我们继续沟通。谢谢!
金 戈
2006年1
Copyright©www.dearbook.com.cn, Inc. All Rights Reserved.