出处:http://www.xinxihua.cn
第一章
软件工程的三个基本策略是本章的重点学习内容。
软件工程的主要环节有:人员管理、项目管理、可行性与需求分析、系统设计、程序设计、测试、维护等。
质量第一,生产率第二。高质量对所有用户都有价值,而生产率只对开发方有意义。质量与生产率之间不存在根本的对立,好的软件工程方法可以同时提高质量与生产率。
软件工程的三个基本策略:
复用:提高质量与生产率;
分而治之:把一个复杂的问题分解为若干个简单的问题,然后解决;
优化——折衷。
一些不正确的软件工程观念:
一、我们拥有一套讲述如何开发软件的书籍,书中充满了标准与示例,可以帮助我们解决软件开发中遇到的任何问题。
二、我们拥有最好的开发工具、最好的计算机,一定能做出优秀的软件。
三、如果我们落后于计划,可以增加更多的程序员来解决。
四、既然需求分析很困难,不管三七二十一先把软件做了再说,反正软件是灵活的,随时可以修改。
一些有争议的观念:
一、如果软件运行较慢,是换一台更快的计算机,还是设计一种更快的算法?
二、有最好的软件工程方法,最好的编程语言吗?
三、编程时是否应该多使用技巧?
四、软件中的错误是否可按严重程度分等级?
所有的错误都是严重的,不存在微不足道的错误。
第二章
管理者不能老惦记着自己是一个官,而应时刻意识到自己是责任的主要承担者。
一个技术出色的程序员可以自豪,但不可以目空一切。上天不可能赋予一个人太多的优点,以至于他没有表示谦虚的余地。
不要让人觉得程序员只管钻研技术,可以不懂世事并且应该自由散漫。程序员不该因为幼稚而显得单纯,应该是成熟了才变得单纯,才配得上这个充满活力的职业。
第三章
软件的高质量并不是“管理”出来的,实质上是设计出来的,质量的管理只是一种预防和认证的手段而已。
项目计划:
知己知彼:项目可用的资源有人、可复用的软构件、软硬件环境。
进度安排:项目计划应是动态的,随着客户需求等变化而变化;进度表要经过开发小组讨论并通过,这样才能实施;进度表中必需确立若干里程碑;进度表中对时间的安排必需有一定的缓冲时间。
以下一些事件经常会导致项目被延误:
(1)上级领导主管臆断,制定了不现实的期限。项目经理与程序员们被迫按照不合理的进度表开展工作。
(2)客户的需求发生了变化,但没有对进度表做出相应的修改。
(3)低估了项目的规模与难度,导致投入的人力和物力不足。
(4)并未预见到存在难以克服的技术障碍。
(5)并未预见到开发人员会发生问题,如生病,辞职等等。
(6)开发人员之间不能很好的交流、协作,导致各阶段任务难以如期完成。
以下是一些有益的建议:
(1)制定进度表的人最好就是项目负责人,他最了解项目和开发人员。进度表要经过开发小组的讨论,在得到大部数人的支持后才能实施。避免出现一厢情愿的局面。
(2)进度安排并不见得一定要符合逻辑顺序。应尽可能地先做技术难度高的事,后做难度低的事。也就是辛苦在前,轻松在后。
(3)开发一个大的软件项目,应该将进度表分为若干个里程碑。一个里程碑之内的多个任务可以同步进行。程序员极容易沉迷于技术,要么乐不思蜀,要么焦头烂额。里程碑就像心灵的灯塔,使忙碌的人群不混乱,不迷失方向。
(4)进度表中必须留有缓冲时间,并将缓冲时间用到不确定的事情上。因为人们对即将要做的事情知之甚少,所以要留一些时间以防不测。Microsoft公司的一些开发小组甚至制定了“50% 缓冲规则”。对许多项目经理而言,容忍进度表中存在缓冲时间,不啻为观念上的一个飞跃。
(5)如果发现项目应交付的期限非常不合理,就要跟领导或跟客户据理力争,请求放宽期限、调整进度。当客户的需求发生变化时,就要对进度表做出相应的修正。不要觉得修改进度表很困难很麻烦,不修改才会产生真真的麻烦。
“零缺陷质量管理”;两大核心为:
高目标:只有确立高目标,才有可能达到较高的质量水平。
可执行的规范:好的规范必需是企业有能力执行的;无规范则导致无序和混沌;太严密的规范则容易扼杀程序员生机勃勃的创造力。
软件的质量因素——简化为以下几种:正确性与精确性(首要考虑的,可扩充到容错性与可靠性);性能与效率;易用性;可理解性与简洁性;可复用性与可扩充性。
质量检查:质量检查应该在每个实践环节都要执行,对应于进度表,在每个里程碑到达时执行质量检查比较合理。检查的内容包括:做出评审及做出建议。
第四章
可行性分析的要素:
技术:能否在指定的时间内完成;能否达到预期的质量标准;能否达到预期的生产效率。
社会环境:产品所处的市场分析;产品及市场受政策影响。
人(团队)
需求分析的困难在于:客户说不清;需求本身经常变动;分析人员或客户理解有误。
需求分析的核心问题:
应该了解什么:由主到次,由宏观到微观。
通过什么方式:与客户交流;向行家请教;分析同行业优秀及失败的软件
失败的需求分析案例和成功的案例一样值得深入分析,成功的案例能把人们引向正确,失败的案例能够引以为戒。
第五章
如果将软件系统比喻为人体,那么:
(1)体系结构就如同人的骨架。
(2)模块就如同人的器官,具有特定的功能。
(3)数据结构与算法就如同人的血脉和神经,它让器官具有生命并能发挥功能。数据结构与算法分布在体系结构和模块中,它将协调系统的各个功能。
(4)用户界面就如同人的外表,最容易让人一见钟情或一见恶心。像人类追求心灵美和外表美那样,软件系统也追求(内在的)功能强大和(外表的)界面友好。但随着生活节奏的加快,人们已少有兴趣去品味深藏不露的内在美。
第六章
由于本章主要介绍C++程序设计方面,所以并未详读,但以下几点十分值得借鉴。
良好的编程风格是产生高质量程序的前提。
(1)宏定义用大写字母加下划线表示,如MAX_LENGTH;
(2)函数用大写字母开头的单词组合而成,如SetName, GetName ;
(3)指针变量加前缀p,如 *pNode ;
(4)BOOL 变量加前缀b,如 bFlag ;
(5)int 变量加前缀i,如 iWidth ;
(6)float 变量加前缀f,如 fWidth ;
(7)double变量加前缀d,如 dWidth ;
(8)字符串变量加前缀str,如 strName ;
(9)枚举变量加前缀e,如 eDrawMode ;
(10)类的成员变量加前缀m_,如 m_strName, m_iWidth ;
对于 int, float, double 型的变量,如果变量名的含义十分明显,则不加前缀,避免烦琐。如用于循环的int型变量 i,j,k ;float 型的三维坐标(x,y,z)等。
将自己经常犯的编程错误记录下来,制成表格贴在计算机旁边。
第七章
测试的目的是为了尽可能多的发现系统的缺陷。
测试有助于提高软件的质量,但是提高软件的质量不能依赖于测试。测试与质量的关系很像在考试中“检查”与“成绩”的关系。 学习好的学生,在考试时通过认真检查能减少因疏忽而造成的答题错误,从而“提高”了考试成绩(取得他本来就该得的好成绩)。 而学习差的学生,他原本就不会做题目,无论检查多么细心,也不能提高成绩。 所以说,软件的高质量是设计出来的,而不是靠测试修补出来的。
开发者在测试自己的程序时存在一些弊病:
(1)开发者对自己的程序印象深刻,并总以为是正确的(自信是应该的)。倘若在设计时就存在理解错误,或因不良的编程习惯而流下隐患,那么他本人很难发现这类错误。
(2)开发者对程序的功能、接口十分熟悉,他自己几乎不可能因为使用不当而引发错误,这与大众用户的情况不太相似,所以自己测试程序难以具备典型性。
(3)程序设计有如艺术设计,开发者总是喜欢欣赏程序的成功之处,而不愿看到失败之处。让开发者去做“蓄意破坏”的测试,就像杀自己的孩子一样难以接受。即便开发者非常诚实,但“珍爱程序”的心理让他在测试时不知不觉地带入了虚假成份。
关于改错的几点思想方法:
(1)要有勇气。程序中的错误只有开发者自己才能找出并改掉。如果因畏惧而拖延,会让你终日心情不定,食无味,睡不香。所以长痛不如短痛,要集中精力对付错误。
(2)不可蛮干。都说急中生智,我不信。我认为大多数人着急了就会蛮干,早把“智”丢到脑后。不仅人如此,动物也如此。
(3)找出错误的根源。我们应该运用归纳、推理等方法尽早确定错误的根源。
(4)在改错之后一定要马上进行重新测试,以免引入新的错误。更加严格的要求是:不论原有程序是否绝对正确,只要对此程序作过改动(哪怕是微不足道的),都要进行重新测试。
第八章
以下一些因素将导致维护工作变得困难:
(1)软件人员经常流动,当需要对某些程序进行维护时,可能已找不到原来的开发人员。只好让新手去“攻读”那些程序。
(2)人们一般难以读懂他人的程序。在勉强接受这类任务时,心里不免嘀咕:“我又不是他肚子里的虫子,怎么知道他如何编程。”
(3)当没有文档或者文档很差时,你简直不知道如何下手。
(4)很多程序在设计时没有考虑到将来要改动,程序之间相互交织,触一而牵百。即使有很好的文档,你也不敢轻举妄动,否则你有可能陷进错误堆里。
(5)如果软件发行了多个版本,要追踪软件的演化非常困难。
(6)维护将会产生不良的副作用,不论是修改代码、数据或文档,都有可能产生新的错误。
(7)维护工作毫无吸引力。高水平的程序员自然不愿主动去做,而公司也舍不得让高水平的程序员去做。带着低沉情绪的低水平的程序员只会把维护工作搞得一塌糊涂。
影响维护代价的非技术因素主要有:
(1)应用域的复杂性。如果应用域问题已被很好地理解,需求分析工作比较完善,那么维护代价就较低。反之维护代价就较高。
(2)开发人员的稳定性。如果某些程序的开发者还在,让他们对自己的程序进行维护,那么代价就较低。如果原来的开发者已经不在,只好让新手来维护陌生的程序,那么代价就较高。
(3)软件的生命期。越是早期的程序越难维护,你很难想象十年前的程序是多么的落后(设计思想与开发工具都落后)。一般地,软件的生命期越长,维护代价就越高。生命期越短,维护代价就越低。
(4)商业操作模式变化对软件的影响。比如财务软件,对财务制度的变化很敏感。财务制度一变动,财务软件就必须修改。一般地,商业操作模式变化越频繁,相应软件的维护代价就越高。
影响维护代价的技术因素主要有:
(1)软件对运行环境的依赖性。由于硬件以及操作系统更新很快,使得对运行环境依赖性很强的应用软件也要不停地更新,维护代价就高。
(2)编程语言。虽然低级语言比高级语言具有更好的运行速度,但是低级语言比高级语言难以理解。用高级语言编写的程序比用低级语言编写的程序的维护代价要低得多(并且生产率高得多)。一般地,商业应用软件大多采用高级语言。比如,开发一套Windows环境下的信息管理系统,用户大多采用Visual Basic、Delphi或Power Builder来编程,用Visual C++的就少些,没有人会采用汇编语言。
(3)编程风格。良好的编程风格意味着良好的可理解性,可以降低维护的代价。
(4)测试与改错工作。如果测试与改错工作做得好,后期的维护代价就能降低。反之维护代价就升高。
(5)文档的质量。清晰、正确和完备的文档能降低维护的代价。低质量的文档将增加维护的代价(错误百出的文档还不如没有文档)。
如果希望软件系统能活下,必须要对它进行维护。如果希望软件系统有效益,则必须设法降低维护的代价。
再生工程主要出于如下愿望:(1)在商业上要提高产品的竞争力;(2)在技术上要提高产品的质量。但这种愿望无法靠软件的维护来实现,因为:(1)软件的可维护性可能极差,实在不值得去做;(2)即使软件的可维护性比较好,但也只是治标不治本。再生工程干脆对已有软件进行全部或部分的改造,赋予软件新的活力。
再生工程与维护的共同之处是没有抛弃原有的软件。如果把维护比作“修修补补”,那么再生工程就算是“痛改前非”。再生工程并不见得一定比维护的代价要高,但再生工程在将来获取的利益却要比通过维护得到的多。