个体过程的改进
Personal Process Improvement
Karl E. Wiegers
过程效果
www.processimpact.com
(注:本文最初发表在2000年5月的《Software Development》杂志上。这次经《Software Development》杂志允许,修改后再次发表。)
目前,过程改进问题是软件领域最热门的话题。然而,很多开发人员不是工作在管理驱动的过程改进组织中。也许你工作在那些倍受日常项目压力影响的严峻环境中,你不会为了以后做出比现在更好的项目而花费精力。一个孤立的个体软件过程热心者又能做哪些工作呢?
即使没有正式的管理规则或领导,你也能采取几种措施来改善你的个体软件工程方法,加快所在工作小组的开发进程。事实证明,你最终也无法影响项目小组以外的人。但是你为提高自身能力所做的任何事情都会为你节省时间、减少修改工作从而提高生产力。Watts Humphrey的个体软件过程(Personal Software Process)为你提供了增强开发能力的有效方法(参考Addison-Wesley出版社1995出版的《软件工程规范》),但不是每一个人都满足苛刻的PSP要求,准备定期承担任务。
建议你花点时间去学习和应用PSP的知识,但是不要在工具和培训上花很多的钱。有选择性的采纳一些常用手段作为个体开发的习惯并向小组成员举例说明要求他们遵守。你不要通过强迫别人的遵守这种方式来推广自己的软件开发知识、技能和手段。因为,当你取得比以前更好的结果时,别人就会注意到,就会遵守。
项目计划和跟踪
大多数开发人员都要为他们的工作做评估准备,但遗憾是其中熟练的评估人员很少。开始时记下你的计划进度和努力作为个人任务和实际结果的评估。比较两组数据然后找出差距,这将有助于你提高自己的评估能力。你也能开发出个体评估方法,比如根据类、方法或GUI(图形用户界面)屏幕和窗口等程序基本元素数量进行评估的方法。数据和经验比凭空臆测更能帮你做好评估。分析数据也有助于你调整管理项目的时间安排。时间安排也许仍与你最初的进度不一致,但是总比你根据个人经验来评估要好的多。
为了进一步提高个体评估能力,你可以为公共的项目活动建立计划检查表,比如,实现一个类、进行一段系统测试或者根据保存在配置管理系统中的组件制作一个产品。这张检查表将帮助你防止遗漏必要的任务,造成过低的评估。更新这张检查表的同时,你也增长了经验。
实际上,因为没有人会在承担的项目上每周花费40个小时并跟踪你到底如何利用时间。因此,你要记下每天在开发或维护阶段花费的小时数。不要精确到每一分钟,这样你会发现一周你有多少真正可以利用的有效项目时间。这个小时数把对任务努力(在劳动时间内)的评估转化成对日历上时间的评估。做计划时,记住要为质量活动、会议、其他任务和不可避免的修改工作留出时间。
即使无法做一个详细的项目计划,你也要写下简短的任务描述从而保证你不会忽略需要执行的步骤。你可以通过维护项目开发记录来保证对每个项目跟踪到底,而不会自以为已经完成了任务确留下一大堆尾巴。当你完成一个项目或完成其中一个阶段时,和小组成员一起对所做的内容进行一次回顾,找出哪些部分进展顺利,哪些还可以进一步完善。这就是过程改进的本质。另外,确定未来项目中你可能遇到的并能控制的难点,
需求
个体开发人员通常无法控制他们面前的软件需求。因此,你应该努力和提供援助的人建立合作关系,无论他们是营销人员、商务分析员、经理还是实际用户。在开始实现项目之前查看所有需求,仔细检查每个功能的需求是否包含设计和完成此功能的全部信息。找出有可能导致你主观臆断的模糊语言。这些不明确的地方很可能使你无法满足客户的期望。注意以下这些模糊词语:支持、例如、与/或、等等、包括、许多、很多、用户友好、简单、典型、标准、通常、快速、健壮、灵活、有效和改良。
当你不确定一个需求的目的时,一定要问清楚。指出你不确定客户需要什么,你不要反复向别人提问,或者当你第一次猜错了时重新建立系统。找出没有指明的暗含的额外条件。考虑你是否能通过测试或者其他什么方法来检验每一个需求都已正确完成。这种严格的检查会让你发现需求中分析员或客户没有看到问题。
当确信掌握了每一个需求的相关前提条件后,你就能按照合理的顺序实现这些需求。最好通过客户代表和技术人员的共同合作来完成前提条件的制定(参考《Software Development》杂志1999年9月的文章“First Things First:Prioritizing Requirements”)。客户通过举例分析或者给出特别规定来评估每个需求的相关价值,与此同时,开发人员可以确定实现每个需求的相关成本和技术难度。
也许你会发现营销人员或商务分析员给出的需求文档无法满足你的要求,因为这些文档结构松散、缺乏实质信息或者存在分散你对关键内容注意的虚假资料。而且你经常会发现,在不同小组之间传阅的关键文档只是根据文档作者个人的理解得出的。例如,营销人员可能写出在他们看来合理但包含太多缺陷而无法让下一环节人员使用的营销需求文档。这有可能是由于他们忽略了产品使用范围和局限性的明确说明,或者缺乏产品使用情况的信息,或者描述了自相矛盾的品质特征等原因造成。
尽量和那些能向你提供关键文档的人员一起工作,并就文档模型达成共识,以满足开发人员的要求。你要向他们解释为什么好的文档结构或内容会减少修改工作量从而加快开发速度。这是使关键文档尽量简洁有效的第一步。
有些花哨功能用户可能会喜欢,但是你要避免这些额外的功能。因为“镀金表面”会增加产品的开发成本,但不会增加产品的价值。同样,向客户代表说明你的这些想法,让他们做出评估,防止他们再提出其他可能的需求。在你开始实现工作以后,如果客户要添加新功能或者要更改需求,你要让客户确实理解新增的成本和工作量。在“客户的需求与产品的某个公开版本或发行版本相关或绑定”结论证实之前,不要实现这些需求。如果客户想要一些小的变动,你要把这些变动加到项目的改动控制过程中去。这将确保你取得优异的商业结果,而这些成果包括了最合理改动,从而增加了你们小组满足项目要求的可能性。
设计和编码
编程中最难的部分不是打字而是设计。在实现软件之前多花点时间设计,避免为了使软件满足功能上和性能上的要求一遍一遍的修改软件。首次规划无法生成最合适的设计。因此,在修改设计之前我会长时间学习。了解、采纳并与同事分享那些标准的设计方法。统一建模语言(UML)是当今热门的设计语言,但是传统的结构化建模技术在一定范围内仍然有效。
模型是交流的基础,因此避免自己创造设计方法。使用那些已经存在的规则可以使交流更有效更容易;不会出现软件障碍问题。与小组成员在设计方法和工具上达成一致,这将有助你获得健壮的软件设计。使用合理的软件设计原则,比如,强内聚、弱耦合、信息隐藏等。
你要熟悉编程工具。实际上,在了解了某种语言、编辑器、编译器和其他工具的性能和局限性后,你能提高效率,增强开发高质量代码的能力。
每个的编程人员都会认为自己的编码风格是最好的,否则,如果他们知道了还有更好的,他们就不会继续保持自己的风格了。即使如此,我们也要向高手学习,提高我们原有的编程方法。读一些经典的编程书籍,比如,Steve McConnell编著的《代码大全》(《Code Complete》,微软出版社,1993),Jon Bentley的《编程拾贝(第二版)》(《Programming Pearls,2nd Edition》,Addison-Wesley出版社,1998),Donald Knuth的三卷巨著《计算机程序设计艺术(第三版)》(《The Art of Computer Programming,3rd Edition》,Addison-Wesley出版社,1998)。在这些巨著的指导下,坚持遵守规则,你就会形成合理的编码标准和良好的结构技巧。例如,在《代码大全》中我看到一种更好的注释方法后,我就修改了自己的注释风格。我知道原来的风格不太好,即使它看上去挺让人喜欢。寻找更好的方法,这种信念鼓舞着我勇敢面对自身的缺点,克服一切困难,不断完善。
在版本控制中,你要维护项目的源代码和其他关键文档,采纳良好的进入/退出检查的配置管理制度。检查一个模块时,你要记录你所作修改的原因。不要为了节省几秒中的打字时间而仅仅输入一串固定的字符或空字符。将系统的编写过程文档化、自动化,可以使项目中的任何人正确的编写程序。培养定期甚至每天测试新编程序的习惯,使用自动的“冒烟”测试法,找出刚产生的bug。
质量测试
每个开发人员对其所担任的工作负责。不幸的是,极少数的开发人员在质量分析和测量、测试及技术检查方面得到过足够的训练。你可以读一些关于软件测试的书,比如,
Brian Marick的《软件测试工艺》(《The Craft of Software Testing》,Prentice Hall出版社, 1997)。然后把学到的知识灵活的运用到你自己的工作中。当你说完成了一个程序的测试时,确定自己所说的意思。你做的已经过时了吗?你对程序做的任何测试,它都通过吗?或者为了使自己达到可接受的质量水平,你是否有意识的挑选了质量筛选方法和测试范围?
有效单元测试是另一个重要的技术。我曾经帮助过一个程序员,他花了三个星期的时间来测试一个程序,但是没有做任何记录。我们不得不重新开始做所有的测试,因为我们不知道他已经作过哪些测试。
通常,只考虑测试情况你也能发现代码中的错误。你可以以代码注释的形式记录你的测试结果,从而使这些测试结果可重复使用。运用自动化测试工具来加速回归测试(regression testing),例如测试那些可通过有条件的编译来调用的函数和方法。当你修改一个程序的时候,通过执行这些回归测试来确保没有其它错误。记录下完整的系统的测试条件,以免日后不得不重做,同时使得其他人在必要时,准确的测试你的程序。发现错误时,添加新的测试条件来帮助你验证每个补丁,形成健壮的回归测试包。
使用质量工具可以帮助你清除代码中尽可能多的潜在问题。至少,你要使用像美国Gimpel 软件公司的Lint,美国康博(Compuware)软件公司NuMega系列中的CodeReview for Visual Basic和Parasoft公司的CodeWizard这类的代码静态分析工具来发现编译器和临时的视觉扫描可能漏掉的微小的错误。一个开发人员曾经告诉我说,当他的小组人员在Lint中运行他们的程序时,Lint报出了10000条错误和警告。发现了10000条错误和警告,这一事实向我表明了那个程序有一些质量问题。“鸵鸟”方法没使程序更可靠。
即使不用Lint工具,也要重视和改正编译器发现的错误和警告。我以前认识的一位最好的程序员教给我将编译器设置到最严格的级别,并听从它告诉你的每一件事。你的开发人员应该使用同样严格的编译器设置并做到一旦发现错误和警告立刻改正过来。如果你的代码有错误,趁现在廉价时把它纠正过来,以免以后付出痛苦的代价。
另一类质量工具是动态代码分析器。例如,Rational软件公司的Purify, 康博(Compuware)软件公司NuMega系列中的BoundsChecker和Parasoft公司的Insure++。这些工具能够发现运行时的错误,像内存溢出、写数组越界以及指针类型不匹配错误。这些工具无法检测出未按用户需求设计的错误或者逻辑上的错误,但是他们能够帮助你缩短调试时间,减少用户的不满。
同事间的测试也是一种提高工作产品质量的有效技术。找一些你在专业方面尊敬的并且个人比较信任的同事,开始检查彼此的需求、设计、代码和测试。听一堂软件检测的课,然后把这些正规的测试引入到你们小组去。很多人抱怨测试花费了太多的时间。虽然他们很费时,但是测试能有效地找到缺陷,任何曾得到过这种好处的人都再也不想去孤立的编程了。测试不会浪费你的时间---- 但Bug却会。(待续)