⾼质量程序设计指南:C++C语⾔(第3版)(修订版)
第1章⾼质量软件开发之道
本章讲述⾼质量软件开发的道理。
为了深⼊理解软件质量的概念,本章阐述了10个重要的软件质量因素,即正确性、健壮性、可靠性、性能、易⽤性、清晰性、安全性、可扩展性、兼容性和可移植性,并介绍了消除软件缺陷的基本⽅法。
⼈们开发软件产品的⽬的是赚钱。为了获得更多的利润,⼈们希望软件开发⼯作“做得好、做得快,并且少花钱”,所以软件质量并不是⼈们唯⼀关⼼的东西。本章论述了“质量、⽣产率和成本”之间的关系,并给出了能够“提⾼质量、提⾼⽣产率,并且降低成本”的软件开发⽅法。
1.1 软件质量基本概念
典型的或本质的特征;②事物固有的或区别于其他事物的
优良或出⾊的程度。
对质量的定义是:①⼀个系统、组件或过程符合特定需求的程度;②⼀
。“正确性”的确很重要,
。如果开发⼈员每天都要⾯对那么多
(修订版)
的质量属性咬⽂嚼字,不久就会迂腐得像孔⼄⼰,因此我们有必要对质量属性做些分类和整合。质量属性可分为两⼤类:“功能性”与“⾮功能性”,后者有时也称为“能⼒”(Capability)。
从实⽤⾓度出发,本章将重点论述“10⼤”质量属性,如表1-1所⽰。
表1-1 “10⼤”软件质量属性
功能性正确性(Correctness)健壮性(Robustness)可靠性(Reliability)
⾮功能性性能(Performance)
易⽤性(Usability)
清晰性(Clarity)
安全性(Security)
可扩展性(Extendibility)兼容性(Compatibility)可移植性(Portability)
其中,功能性质量属性有3个:正确性、健壮性和可靠性;⾮功能性质量属性有7个:性能、易⽤性、清晰性、安全性、可扩展性、兼容性和可移植性。
为什么碰巧是“10⼤”呢?
不为什么,只是⽅便记忆⽽已(如同国际、国内经常评“10⼤”那样)。
为什么“10⼤”⾥⾯不包括可测试性、可维护性、灵活性呢?它们不也是很重要的吗?
它们是很重要,但不是软件产品的卖点,所以挤不进“10⼤”⾏列。我认为如果做好了上述“10⼤”质量属性,软件将会⾃然⽽然地具备良好的可测试性、可维护性。⼈们很少纯粹地去提⾼可测试性和可维护性,勿要颠倒因果。⾄于灵活性,它有益处也有坏处,该灵活的地⽅已经被其他属性覆盖,⽽不该灵活的地⽅就不要刻意去追求。
根据经验,如果你想⼀股脑⼉地把任何事情都做好,结果通常是什么都做不好,做事总是要分主次的。什么是重要的质量属性,应当视具体产品的特征和应⽤环境⽽定,请读者不要受本书观点的限制。最简单的判别⽅式就是考察该质量属性是否被⽤户关注(即卖点)。
1.1.2 提⾼软件质量的基本⽅法
质量的死对头是缺陷,缺陷是混在产品中的⼈们不喜欢、不想要的东西。缺陷越多质量越低,缺陷越少质量越⾼。
Bug是缺陷的形象⽐喻,⼈们喜欢说Bug是因为可以把Bug当作“替罪⽺”。软件的缺陷明明是⼈造成的,有了Bug这个词后就可以把责任推给Bug——“都是Bug 惹的祸”。唉,当⼀只Bug真是太冤枉了!
2High Quality Programming
第1章
⾼质量软件开发之道软件存在缺陷吗?是的,有以下典故为证。
编程⼤师说:“任何⼀个程序,⽆论它多么⼩,总存在着错误。”
初学者不相信⼤师的话,他问:“如果有个程序⼩得只执⾏⼀个简单的功能,那会怎么样?”
“这样的程序没有意义,”⼤师说,“但如果这样的程序存在的话,操作系统最后将失效并产⽣错误。”
但初学者不满⾜,他问:“如果操作系统不失效,那会怎么样?”
“没有不失效的操作系统,”⼤师说,“但如果这样的操作系统存在的话,硬件最后将失效并产⽣错误。”
初学者仍不满⾜,继续问:“如果硬件也不失效,那会怎么样?”
⼤师长叹⼀声道:“没有不失效的硬件。但如果这样的硬件存在的话,⽤户就会想让那个程序做⼀件不同的事,这件事也是个错误。”
没有错误的程序世间难求。(摘⾃《编程之道》)
错误是严重的缺陷。医⽣犯的错误最终会被埋葬在地下,从此⼀了百了。但软件的错误不会⾃动消失,它会⼀直骚扰⽤户。据统计,对于⼤多数的软件产品⽽⾔,⽤于测试与改错的⼯作量和成本将占整个软件开发周期的30%,这是巨⼤的浪费。如果不懂得如何有效地提⾼软件质量,项⽬会付出很⾼的代价,你(开发⼈员)不仅没有功劳,也没⼈欣赏你的苦劳,你拥有最多的将只是疲劳。
怎样才能提⾼软件的质量呢?
还是先来听⼀个中国郎中治病的故事吧!
在中国古代,有⼀家三兄弟全是郎中。其中有⼀⼈是名医,⼈们问他:“你们兄弟三⼈谁的医术最⾼?”
他回答说:“我常⽤猛药给病危者医治,偶尔有些病危者被我救活,于是我的医术远近闻名并成了名医。我⼆哥通常在⼈们刚刚⽣病的时候马上就治愈他们,临近村庄的⼈都知道他的医术。我⼤哥深知⼈们⽣病的原因,所以能够预防家⾥⼈⽣病,他的医术只有我们家⾥才知道。”
提⾼软件质量的基本⼿段是消除软件缺陷。与上述三个郎中治病很相似,消除软件缺陷也有三种基本⽅式:
(1)在开发过程中有效地防⽌⼯作成果产⽣缺陷,将⾼质量内建于开发过程之中。这就是“预防胜于”的道理,⽆疑是最佳⽅式,但是要求开发⼈员必须懂得正确地做事(门槛⽐较⾼)。我们学习“⾼质量编程”的⽬的就是要在⼲活的时候⼀次性编写出⾼质量的程序,⽽不是在程序出错后才去修补。
(2)当⼯作成果刚刚产⽣时马上进⾏质量检查,及时出并消除⼯作成果中的缺陷—这种⽅式效果⽐较好,⼈们⼀般都能学会。最常⽤的⽅法是技术评审、测试和质量保证等(详见本章1.4节),已经被企业⼴泛采⽤并取得了成效。
(3)当软件交付给⽤户后,⽤着⽤着就出错了,赶紧请开发者来补救,这种⽅
High Quality Programming3
(修订版)
式的代价最⾼。可笑的是,当软件系统在⽤户那⾥出故障了,那些现场补救成功的⼈倒成了英雄,好⼼⽤户甚⾄还寄来感谢信。?
1.1.3 “零缺陷”理念
质量的最⾼境界是什么?是尽善尽美,即“零缺陷”。
“零缺陷”理念来源于国际上⼀些著名的硬件⼚商。尽管软件的开发与硬件⽣产有很⼤的区别,但我们仍可以借鉴,从中得到启迪。
⼈在做⼀件事情时,由于存在很多不确定的因素,⼀般不可能100%地达到⽬标。
假设平常⼈做事能完成⽬标的80%。如果某个⼈的⽬标是100分,那么他最终成绩可达80分;如果某个⼈的⽬标只是60分,那么他最终成绩只有48分。我们在考场上⾝经百战,很清楚那些只想混及格的学⽣通常都不会及格。即使学习好的学⽣也常有失误,因⽽捶胸顿⾜。
做⼀个项⽬通常需要多⼈协作。假设某系统的总质量是10个开发⼈员的⼯作质量之积,即最⾼值为1.0,最低值为0。如果每个⼈的质量⽬标是0.95,那么10个⼈的累积质量不会超过0.598。如果每个⼈的质量⽬标是0.9,那么10个⼈的累积质量不会超过0.35。只有每个⼈都做到1.0,系统总质量才会是1.0。只要其中⼀⼈的⼯作质量是0,那么系统总质量也就成了0。因系统之中的⼀个缺陷⽽导致机毁⼈
亡的事件已不罕见。
上述⽐喻虽然严厉了⼀些,但从严要求只有好处没有坏处。如果不严以律⼰,⼈的堕落就会很快。如果没有“零缺陷”的质量理念,也许缺陷就会成堆。
从理念到⾏动还是有⼀定距离的,企业在开发产品时应当根据⾃⾝实⼒和⽤户的期望值来设定可以实现的质量⽬标。过低的质量⽬标会毁坏企业的声誉,⽽过⾼
1.3节)。
1.2 细说软件质量属性
1.2.1 正确性
正确性是指软件按照需求正确执⾏任务的能⼒。这⾥“正确性”的语义涵盖了“精确性”。正确性⽆疑是第⼀重要的软件质量属性。如果软件运⾏不正确,将会给⽤户造成不便甚⾄损失。技术评审和测试的第⼀关都是检查⼯作成果的正确性。
正确性说起来容易做起来难。因为从“需求开发”到“系统设计”再到“实现”,任何⼀个环节出现差错都会降低正确性。机器不会主动欺骗⼈,软件运⾏出错通常都是⼈造成的,所以不要借⼝埋怨机器有⽑病。开发任何软件,开发者都要为“正确”两字竭尽全⼒。
1.2.2 健壮性
健壮性是指在异常情况下,软件能够正常运⾏的能⼒。正确性与健壮性的区别4High Quality Programming
第1章
⾼质量软件开发之道
是:前者描述软件在需求范围之内的⾏为,⽽后者描述软件在需求范围之外的⾏为。
可是正常情况与异常情况并不容易区分,开发者往往要么没想到异常情况,要么把异常情况错当成正常情况⽽不做处理,结果降低了健壮性。⽤户才不管正确性与健壮性的区别,反正软件出了差错都是开发⽅的错。所以提⾼软件的健壮性也是开发者的义务。
健壮性有两层含义:⼀是容错能⼒,⼆是恢复能⼒。
容错是指发⽣异常情况时系统不出错误的能⼒,对于应⽤于航空航天、武器、⾦融等领域的这类⾼风险系统,容错设计⾮常重要。
容错是⾮常健壮的意思,⽐如UNIX的容错能⼒很强,很难使系统出问题。⽽恢复则是指软件发⽣错误后(不论死活)重新运⾏时,能否恢复到没有发⽣错误前的状态的能⼒。c语言编程入门指南pdf
从语义上理解,恢复不及容错那么健壮。
例如,某⼈挨了坏蛋⼀顿拳脚,特别健壮的⼈⼀点事都没有,表⽰有容错能⼒;⽐较健壮的⼈,虽然被打倒在地,过了⼀会还能爬起来,除了⽪⾁之痛外倒也不⽤去医院,表⽰恢复能⼒⽐较强;⽽虚弱的⼈可能短期恢复不过来,得在病床上躺很久。
恢复能⼒是很有价值的。Microsoft公司早期的窗⼝系统,如Windows 3.x和Windows 9x,动不动就死机,其容错性的确⽐较差。但它们的恢复能⼒还不错,机器重新启动后⼀般都能正常运⾏,看在这个份上,⼈们也愿意将就着⽤。
1.2.3 可靠性
可靠性不同于正确性和健壮性,软件可靠性问题通常是由于设计中没有料到的异常和测试中没有暴露的代码缺陷引起的。可靠性是⼀个与时间相关的属性,指的是在⼀定环境下,在⼀定的时间段内,程序不出现故障的概率,因此是⼀个统计量,通常⽤平均⽆故障时间(MTTF, mean-time to fault)来衡量。
可靠性本来是硬件领域的术语。⽐如某个电⼦设备在刚开始⼯作时挺好的,但由于器件在⼯作中其物理性质会发⽣变化(如发热、⽼化等),慢慢地系统的功能或性能就会失常。所以⼀个从设计到⽣产完全正确的硬件系统,在⼯作中未必就是可靠的。
⼈们有时把可靠性叫做稳定性。
软件在运⾏时不会发⽣物理性质的变化,⼈们常认为如果软件的某个功能是正确的,那么它⼀辈⼦都是正确的。可是我们⽆法对软件进⾏彻底的测试,⽆法根除软件中潜在的错误。平时软件运⾏得好好的,说不准哪⼀天就不正常了,如有千年等⼀回的“千年⾍”问题、司空见惯的“内存泄露”问题、“误差累积”问题,等等。
因此把可靠性引⼊软件领域是很有意义的。
软件可靠性分析通常采⽤统计⽅法,遗憾的是⽬前可供第⼀线开发⼈员使⽤的成果很少见,⼤多数⽂章限于理论研究。我曾买了⼀本关于软件可靠性的著作,此书充满了数学公式,实在难以看懂,更不知道怎样应⽤。请宽恕我的愚昧,我把此“天
书”给“供养”起来,没敢⽤笔画⼀处记号。
High Quality Programming5
(修订版)
⼝语中的可靠性含义宽泛,⼏乎囊括了正确性、健壮性。只要⼈们发现系统有⽑病,便归结为可靠性差。从专业⾓度讲,这种说法是不对的,可是我们并不能要求所有的⼈都准确地把握质量属性的含义。
有必要搞清楚“故障”和“错误”这两个容易混淆的概念。
在《现代英汉词典》⾥,“故障(Fault)”⼀词的定义是:使设备、部件或元件不能按所要求的⽅式运⾏的⼀种意外情况,可能是物理的也可能是逻辑的。
那些潜伏在代码中的错误往往是不明显的,之所以在测试的时候没有暴露,是因为测试时的环境和条件不⾜以使之暴露,更何况我们⽆法对代码进⾏最彻底的测试。由此可见,故障是在经过⽇积⽉累,满⾜了⼀定的条件之后才出现的。例如,“千年⾍”问题,“内存泄漏(吃内存)”导致内存耗尽,“误差累积”导致计算错误进⽽导致连锁反应,“性能开销累积”导致性能显著下降,等等。因此,故障通常都是不可预料的、灾难性的。
“错误”的含义要⼴泛得多,例如,语法错误、语义错误、⽂件打开失败、动态存储分配失败等。⼀般说来,程序错误是可以预料的,因此可以预设错误处理程序,运⾏时这些错误⼀旦发⽣,就可以调⽤错误处理程序把它⼲掉,程序还可以继续运⾏。因此,错误的结果⼀般来说不是灾难性的。
1.2.4 性能
性能通常是指软件的“时间—空间”效率,⽽不仅是指软件的运⾏速度。⼈们总希望软件的运⾏速度快些,并且占⽤资源少些。旧社会地主就是这么对待长⼯的:⼲活要快点,吃得要少点。
程序员可以通过优化数据结构、算法和代码来提⾼软件的性能。算法复杂度分析是很好的⽅法,可以达到“未⼘先知”的功效。
性能优化的⽬标是“既要马⼉跑得快,⼜要马⼉吃得少”,关键任务是出限制性能的“瓶颈”,不要在⽆关痛痒的地⽅瞎忙活。例如,在⼤学⾥当教师,光靠卖⼒⽓地讲课或者埋头做实验,职称是升不快的。有些⼈到了突破⼝,⼀年之内“造”
⼏⼗篇⽂章,争取破格升副教授、教授。在学术上⾛捷径,这类“学者”的质量真让⼈担忧。
性能优化就好像从海绵⾥挤⽔⼀样,你不挤,⽔就不出来,你越挤海绵越⼲。
有些程序员认为现在的计算机不仅速度越来越快,⽽且内存越来越⼤,因此软件性能优化的必要性下降了。这种看法是不对的,殊不知随着机器的升级,软件系统也越来越庞⼤和复杂了,性能优化仍然⼤有必要。最具有代表性的是三维游戏软件,如《Delta Force》、《古墓丽影》、《反恐精英》等,如果不对软件(关键是游戏引擎)做精益求精的优化,要想在⼀台普通的PC上顺畅地玩游戏是不太可
能的。
1.2.5 易⽤性
易⽤性是指⽤户使⽤软件的容易程度。现代⼈的⽣活节奏快,⼲什么事都可能想图个⽅便,所以把易⽤性作为重要的质量属性⽆可⾮议。
导致软件易⽤性差的根本原因是开发⼈员犯了“错位”的⽑病:他以为只要⾃6High Quality Programming
第1章
⾼质量软件开发之道
⼰⽤起来⽅便,⽤户也⼀定会满意。俗话说“王婆卖⽠,⾃卖⾃夸”。当开发⼈员向⽤户展⽰软件时,常会得意地讲:“这个软件⾮常好⽤,作给你看,……是很好⽤吧!”
软件的易⽤性要让⽤户来评价。如果⽤户觉得软件很难⽤,开发⼈员不要有逆反⼼理:哪⾥来的笨蛋!
其实不是⽤户笨,是⾃⼰开发的软件太笨了。当⽤户真的感到软件很好⽤时,⼀股温暖的感觉就会油然⽽⽣,于是就会⽤“界⾯友好”、“⽅便易⽤”等词来夸奖软件的易⽤性。
1.2.6 清晰性
清晰意味着⼯作成果易读、易理解,这个质量属性表达了⼈们的⼀种质朴的愿望:让我花钱买它或者⽤它,总得让我看明⽩它是什么东西。我⼩时候的⼀个伙伴在读中学时就因搞不明⽩电荷为什么还要分“正”和“负”,觉得很烦恼,便早早地辍学当了⼯⼈。
开发⼈员只有在⾃⼰思路清晰的时候才可能写出让别⼈易读、易理解的程序和⽂档。可理解的东西通常是简洁的。⼀个原始问题可能很复杂,但⾼⽔平的⼈就能够把软件系统设计得很简洁。如果软件系统臃肿不堪,它迟早会出问题。所以简洁是⼈们对⼯作“精益求精”的结果,⽽不是潦草应付的结果。
在⽣活中,与简洁对⽴的是“唆”。废话⼤师有句名⾔:“如果我令你过于
轻松地明⽩了,那你⼀定是误解了我的意思。”中国⼩说中最“婆婆妈妈”的男⼈是唐僧。有⼀项民意调查:如果世上只有唐僧、孙悟空、猪⼋戒和沙僧这四类男⼈,你要嫁给哪⼀类?请列出优先级。调查结果表明,现代⼥性毫不例外地把唐僧摆在最后。
很多⼈在读研究⽣时有⼀种奇怪的体会:如果把⽂章写得很简洁,让⼈很容易理解,投稿往往中不了,只有加上⼀些⽞乎的东西,把本来简单的东西弄成复杂的,才会增加投稿的命中率。虽然靠这种做法可能有效,可千万不要把此“经验”应⽤到产品的开发中!
1.2.7 安全性
这⾥的安全性是指信息安全,英⽂是Security⽽不是Safety。安全性是指防⽌系统被⾮法⼊侵的能⼒,既属于技术问题⼜属于管理问题。信息安全是⼀门⽐较深奥的学问,其发展是建⽴在正义与邪恶的⽃争之上的。这世界似乎不存在绝对安全的系统,连美国军⽅的系统都频频遭⿊客⼊侵。如今全球⿊客泛滥,真是“道⾼⼀尺,魔⾼⼀丈”啊!
对于⼤多数软件产品⽽⾔,杜绝⾮法⼊侵既不可能也没有必要。因为开发商和客户愿意为提⾼安全性⽽投⼊的资⾦是有限的,他们要考虑值不值得。究竟什么样的安全性是令⼈满意的呢?
⼀般地,如果⿊客为⾮法⼊侵花费的代价(考虑时间、费⽤、风险等多种因素)
High Quality Programming7
(修订版)
⾼于得到的好处,那么这样的系统就可以认为是安全的。
1.2.8
可扩展性反映了软件适应“变化”的能⼒。在软件开发过程中,“变化”是司空见惯的事情,如需求、设计的变化,算法的改进、程序的变化等。
由于软件是“软”的,是否它天⽣就容易修改以适应“变化”?
关键要看软件的规模和复杂性。
如果软件规模很⼩,问题很简单,那么修改起来的确⽐较容易,这时就⽆所谓“可扩展性”了。要是软件的代码只有100⾏,那么“软件⼯程”也就⽤不着了。
如果软件规模很⼤,问题很复杂,倘若软件的可扩展性不好,那么该软件就像⽤卡⽚造成的房⼦,抽出或者塞进去⼀张卡⽚都有可能使房⼦倒塌。可扩展性是系统设计阶段重点考虑的质量属性。
1.2.9 兼容性
兼容性是指两个或两个以上的软件相互交换信息的能⼒。由于软件不是在“真空”⾥应⽤的,它需要具备与其他软件交互的能⼒。例如,两个字处理软件的⽂件格式兼容,那么它们都可以操作对⽅的⽂件,这种能⼒对⽤户很有好处。国内⾦⼭公司开发的字处理软件WPS就可以操作Word⽂件。
兼容性的商业规则是:弱者设法与强者兼容,否则⽆容⾝之地;强者应当避免被兼容,否则市场将被⽠分。如果你经常看⾹港拍的“⿊帮”影⽚,你就很容易明⽩这个道理。所以WPS⼀定要与Word兼容,否则活不下去。但是Word绝对不会与WPS兼容,除⾮WPS在中国称⽼⼤。
1.2.10 可移植性

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。