购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

前言

在20世纪60年代后期,人们对计算机软件的需求已经超过了技术学校、学院和大学培养计算机专业人员开发软件的能力——这种现象后来被称为软件危机。提高高校的人才产出并不是一个切实可行的方法,因为报考计算机科学专业的合格学生太少,无法满足实际的需求。当时,研究人员认为,一种更好的解决方案是提高现有计算机程序员的生产力。由于注意到软件开发和其他工程活动之间的相似之处,这些研究人员得出结论,其他工程学科中的流程和策略可以用来帮助解决软件危机。因此,软件工程(software engineering)诞生了。

在软件工程蓬勃发展之前,软件开发一直是一门神秘的手艺,掌握在拥有不同能力和成就的大师们手中。当时,一个软件项目的成功完全取决于一两个关键程序员的能力,而不是整个团队的能力。而软件工程的出现,正是为了平衡软件团队成员之间的各种技能,使他们更加具有生产力,并且减少对那一两个关键程序员的依赖。

在很大程度上,软件工程的实践已经被证明是成功的。由众多程序员团队构建的大型项目,不可能再使用过去那种特别的组织方式来完成。但与此同时,一些重要的品质也丢失了。软件工程以牺牲个人的创造力、技能和成长为代价,来提高团队的生产力。尽管软件工程技术有可能将糟糕的程序员变成优秀的程序员,但它们也会限制优秀程序员发挥最佳的工作能力。毕竟,这个世界上卓越的程序员太少了。我们最不愿意做的事情就是阻止程序员去发挥他们的潜能,然而,这正是软件工程经常会做的事情。

《编程卓越之道》系列图书,旨在恢复一些已经失去的个人创造力、技能和成长性。它涵盖了我称之为个人软件工程的内容,或者说一个程序员应该如何提高他的代码质量。具体来说,它会告诉你如何编写出卓越的代码——易于维护、扩展、测试和调试、文档化、可部署的代码,甚至是易于丢弃的代码。卓越的代码会避免代码拼凑和使用奇技淫巧,而这些会给工程师和管理者带来不可预料的压力或者错误的计划。卓越的代码应该是那些你可以引以为豪的代码。

当我编写完《编程卓越之道 第二卷:运用底层语言思想编写高级语言代码》(张菲译,电子工业出版社出版)一书时,我打算在第3卷中加入更多的内容。在第2卷的最后一章中,我写下了以下内容:

《编程卓越之道(卷3):软件工程化》会开始讨论编程领域的“个人软件工程”。软件工程领域主要关注管理大型软件系统,而个人软件工程主要关注个体层面如何编写卓越的代码,即创作中的技巧、艺术和愉悦感。我们将在第3卷中通过对软件开发、软件开发人员以及系统文档(重点添加)的讨论,来详细剖析个人软件工程的各个方面。

系统文档(包括需求文档、测试过程文档、设计文档等)是软件工程的重要组成部分。因此,一本关于这些主题的书,至少应该提供对它们的概要介绍。但是,在编写了7章内容之后,我开始意识到无法在一本书里涵盖所有这些内容。因此,最后我把《软件工程化》这本书又分成了4卷。其中第1卷就是这本书,它是《编程卓越之道》系列的第3卷,主要介绍软件开发模型和系统文档。该系列的第4卷主要介绍软件设计,第5卷将进一步介绍如何编写卓越的代码,第6卷主要介绍有关测试的内容。

在我编写本书时,距离我完成《编程卓越之道》系列的第2卷已经过去了10年。现在是完成第3卷的时候了,即使这意味着要将原来的内容拆分成两卷甚至更多卷。如果你读过我早期出版的书,就会知道我喜欢深入探讨一些话题,我对编写那些只介绍皮毛的书不感兴趣。因此,我所面临的问题是,要么将一本书的内容拆分到多本书中,要么制作一本超过2000页的大部头,历史证明,这本大部头很可能永远无法完成。我向那些期待本书应该涵盖更多内容的人道歉,但是请不用担心,这些内容都会被包含在陆续出版的分卷中。在本书中,你会更快地了解第一部分内容。

假设和前提

为了专注于介绍软件工程化的相关内容,本书必须先进行一些假设。虽然我已经尽力减少这些假设条件,但是如果你的个人技能可以满足一些前提条件,那么你将从本书中得到更多的收获。

你应该至少精通一种命令式(过程式)或面向对象的编程语言,包括C和C++、C#、Swift、Pascal、BASIC、Java以及汇编语言。你应该知道如何描述一个小问题,并通过软件的设计和实现来解决它。对于本书而言,如果你在大学中学习过一个学期或一个季度的专业课程,或者有过几个月的实际编程经验,应该就足够了。

你还应该对计算机原理和数据结构有基本的了解。例如,你应该了解十六进制和二进制编码,以及计算机如何在内存中表示各种高级数据类型,如有符号整数、字符和字符串。如果你觉得自己在这方面的知识比较薄弱,请阅读《编程卓越之道 第一卷:深入理解计算机》中对计算机原理的介绍。尽管我可能会偶尔引用第1卷中的内容,但是你应该也可以独立阅读本书。

什么是卓越的代码

卓越的代码是按照一套可以指导程序员在编码时做出决策的规则,所编写出来的软件。在和其他程序员一起编写卓越的代码时,时刻要注意编写相关文档,使得其他人也可以阅读、理解和维护软件。我认为这套规则是软件开发的黄金法则,是软件工程的关键核心。

具体一点,卓越的代码就是:

● 运行速度快,可以有效地利用CPU、系统资源和内存的代码。

● 文档良好,易于阅读、维护和扩展的代码。

● 遵循一套统一编程风格的代码。

● 经过明确的设计,遵循已建立的软件工程约定的代码。

● 经过良好的测试,运行稳定的代码。

● 效率高、成本低的代码。

虽然《编程卓越之道》系列的第1卷和第2卷都讨论了卓越代码的许多方面,但是本系列的其余分卷(从本卷开始)会特别关注如何编写满足上述标准的代码。

程序员分类

为了理解是什么造就了卓越的程序员,让我们首先来思考业余程序员、不同级别的程序员和软件工程师之间的区别。

业余程序员

业余程序员是指自学成才、只有很少编程经验的人,因此与我们说的卓越的程序员相反。在计算机行业发展的早期阶段,这些程序员被称为黑客。现在这个术语已经演变出一些不同的含义,不一定用来描述一个没有足够教育背景或者编程经验,但是从事专业级别软件工程的程序员。

业余程序员编写的代码的问题在于,他们通常只为自己或者朋友编写代码,因此,这些代码通常不符合现代软件工程的项目标准。但是,业余程序员可以通过少量的培训教育(正如《编程卓越之道》系列图书所提供的帮助)来提高他们的水平。

程序员

计算机程序员涵盖了广泛的经验和职责范围,通常可以从初级程序员、编码人员、一级程序员和二级程序员、分析师/系统分析师以及系统架构师等岗位头衔上反映出来。这里我们将探讨其中的一些角色以及它们之间的区别。

实习生

实习生通常是指做兼职工作的学生,他们会被分配一些所谓的烦琐工作,比如运行一套固定的测试程序,或者为软件编写文档。

初级程序员

刚毕业的学生通常会填补初级程序员的岗位。通常,他们会从事测试或者维护的工作。他们很少有机会从事新项目的开发;相反,他们的大部分编程时间都花在重新编写已有的代码逻辑,或者处理遗留代码上。

编码人员

当初级程序员获得了足够的经验,让管理层信任他们可以为项目开发新的代码时,他们就可以晋升为编码人员。较资深的程序员会将一个大项目的一些(不太复杂的)子模块分配给这些编码人员,以帮助自己更快地完成项目。

一级程序员和二级程序员

当程序员获得了更多的经验,并且能够自己编写复杂的代码时,他们会从编码人员晋升为一级程序员,然后晋升为二级程序员。系统分析师通常会向一级程序员和二级程序员提供他们的一个大概设想,而一级程序员和二级程序员能够帮助补充所缺少的细节部分,并且开发出符合系统分析师期望的应用程序。

系统分析师

系统分析师会研究某个问题,并且确定实现某种解决方案的最佳方法。通常,系统分析师会选择要使用的主要算法,以及组建最终开发应用程序的团队。

系统架构师

系统架构师会根据系统分析师设计的多个组件,选择如何让它们在一个更大的系统中协同工作。通常,系统架构师会指定软件开发流程、硬件,以及其他与软件无关的事项,作为整个解决方案的一部分。

终极程序员

终极程序员是所有这些细分职责的组合。也就是说,终极程序员能够研究一个问题,设计一种解决方案,用某种编程语言实现该解决方案,并且测试最终的结果。

程序员分类的问题

实际上,大多数对程序员的分类都是人为决定的,只是为了证明对新手程序员和有经验的程序员提供不同的工资标准是合理的。例如,系统分析师为指定的应用程序设计算法和总体数据流,然后将设计交给编码人员,由编码人员用特定的编程语言来实现该设计。我们通常不会将这两项工作与编程联系起来,因为尽管初级程序员完全有能力将一个设计转换成一种合适的编程语言,但是他们没有从头开始设计大型系统的经验。系统分析师和系统架构师通常具有负责整个项目的经验和能力,但是管理层通常会发现,在项目中让系统分析师和系统架构师发挥他们的经验,要比让他们做一个毕业生可以做的低层次的编码工作更划算(因为成本更低)。

软件工程师

在传统工程领域,工程师通常会遵循一套既定的规则,通过组合已知的解决方案来建立一种新的解决方案,从而达到解决某个特定问题的目的。这种方法甚至可以让普通的工程师有效地解决问题,而不必从头开发一个系统。软件工程将传统的工程理念应用到软件开发领域,从而最大化整个开发团队的价值。在很大程度上,“软件工程革命”是成功的。拥有适当培训和领导能力的软件工程师,可以用比以前更少的时间和更低的成本,编写出更高质量的代码。

纯粹的软件工程并不鼓励发散思维,因为它有浪费时间并将工程师引向失败之路的风险(会导致更高的开发成本和更长的开发时间)。一般来说,软件工程更关心的是如何在预算范围内按时开发完成应用程序,而不是尽可能用最好的方式来编写代码。但是,如果软件工程从业者们从来没有尝试过任何新的东西,那么他们常常会错过产生伟大设计的机会,永远无法在规则手册中增加任何实践原则,也永远无法成为卓越的程序员。

卓越的程序员

卓越的程序员能够认识到成本问题,但是他们也能够意识到,探索新的想法和方法论对于推进这一领域很重要。他们知道什么时候必须遵守规则,也知道什么时候可以打破(或至少绕过)规则。最重要的是,卓越的程序员会将他们的技能发挥到极限,取得那些不是通过简单思考就能够达到的成就。黑客是天生的,软件工程师是后天培养的,而卓越的程序员则两者兼而有之。他们有三个主要的特征:对工作真正地热爱,持续不断地接受教育和培训,以及拥有在解决问题时跳出思维定式的能力。

热爱你的工作,做你热爱的工作

人们往往擅长做自己喜欢的工作,而不擅长做自己不喜欢的工作。最重要的是,如果你讨厌计算机编程,那么你就不可能成为一个很好的计算机程序员。如果你天生没有解决问题和克服挑战的欲望,那么再多的教育和培训也改变不了你的性格。因此,如果你想成为一个卓越的程序员,那么最重要的先决条件就是你真的喜欢编写计算机程序。

优先接受教育和培训

卓越的程序员喜欢挑战这个领域中各种类型的问题,但他们还需要其他一些东西——正规的教育和培训。我们将在后面的章节中更深入地讨论教育和培训的作用,但就目前而言,我们知道卓越的程序员一定是受过良好教育的(也许受过高等以上教育),并且他们在整个职业生涯中持续接受教育就足够了。

跳出思维定式

如上所述,遵循一套预先定义的规则来开发代码,是软件工程师的典型特征。然而,正如你将在第1章中所看到的,要想成为一个卓越的程序员(“编程大师”),你需要愿意并且能够设计出新的编程技术,而这些技术只能来自发散的思维,而非盲目地循规蹈矩。卓越的程序员有一种内在的欲望去突破他们的极限,不断探索新的解决方案。

如果你想成为一个卓越的程序员

总而言之,如果你想成为一个真正卓越的程序员,并获得同行的尊敬,你需要拥有以下几个特点:

● 对计算机编程和解决问题热爱。

● 在专科或者本科的基础上 ,拥有广泛的计算机科学知识。

● 终身接受教育和培训。

● 具有在探索解决方案时能够跳出固有思维定式的能力和意愿。

● 具有总是以最好的方式完成某项任务和工作的愿望与动力。

在拥有以上这些特点之后,唯一能够阻止你成为一个卓越的程序员的就是新的知识,而这也是本书的价值所在。

最后一点关于道德和个人性格的说明

软件工程师的工作是在面临众多相互冲突的需求的情况下,通过在系统设计中做出适当的妥协来创造出最好的产品。在此过程中,软件工程师必须对需求的优先级进行排序,并根据项目的约束条件来选择解决问题的最佳方案。在较为复杂的项目,尤其是压力较大的项目中,道德和个人性格通常会影响他们的决策。理智上的不诚实(例如,夸大项目评估,或者声称软件的某一部分没有经过完全测试)、使用盗版软件开发工具(或者其他软件)、未经许可在软件中引入没有文档的功能(比如后门程序),或者态度傲慢(认为自己比其他团队成员都好),这些都是软件工程道德缺失的例子。遵守良好的道德准则和践行良好的道德规范,将使你成为一个更好的人,以及一个更好的程序员。

获取更多信息

Robert N Barger编写的 Computer Ethics:A Case-Based Approach ,英国剑桥大学出版社,2008年。

Floridi Luciano编写的 The Cambridge Handbook of Information and Computer Ethics ,英国剑桥大学出版社,2006年。

Tom Forester和Perry Morrison编写的 Computer Ethics:Cautionary Tales and Ethical Dilemmas in Computing 2nd ,麻省理工学院出版社,1993年。

Donn B Parker的Rules of Ethics in Information Processing ,发表于《ACM通讯》杂志1968年第11卷第3期,第198-201页。

Norbert Wiener编写的 The Human Use of Human Beings:Cybernetics and Society ,波士顿霍顿米夫林出版公司,1950年。

WikiWikiWeb上的文章 Grand Master Programmer ,最后更新于2014年11月23日。

读者服务

微信扫码回复:43993

● 加入本书读者交流群,与更多同道中人互动

● 获取【百场业界大咖直播合集】(持续更新),仅需1元 db0/T0cfkerfGxtClislBhY4HyHkCuTmxRiANmSPCppMg1OQypno50tckvnqMvv8

点击中间区域
呼出菜单
上一章
目录
下一章
×