原文作者:Tom Demarco,写于2009年7月

作者简介:Tom DeMarco是大西洋系统协会(www.atlsysguild.com)的负责人。他的职业生涯开始于贝尔实验室,是结构化分析和设计的创始人之一,研究领域主要集中在对软件组织和项目的风险管理。已经出版了好几本经典图书,包括《人件》、《最后期限》、《与熊共舞》等。

遥想当年在德国的加米施举行的NATO(North Atlantic Treaty Organization,即北大西洋公约组织)软件工程大会,迄今已有40载了。在那次会议上,软件工程(Software Engineering)作为一门学科被首次提出。因为我早年的一些工作成果被吸收入那个新学科,现在似乎是时候来重新评估一下了。

我早年写过一本关于软件度量的书,书名叫《Controlling Software Projects: Management, Measurement, and Estimates》(由Prentice Hall出版社于1986年出版)。很多初露头角的软件工程师在量化工作和规划项目时都把那本书奉为圭璧。如今我在反思之中,我想知道:书里的建议在那时候正确吗?现在还有用吗?我现在仍然相信“度量”是任何成功的软件开发活动所必需的吗?我的回答全部是否定的。

在我看来,那本书是一种古怪的组合——书里每一页上写的东西大体都是正确的,但把它们组合起来形成的中心思想却走向了谬误。似乎年轻的作者从未遇到过一个他不喜欢的度量。那本书诠释的内涵似乎是:度量是好东西,多多益善,我们应该来者不拒。现如今,我们都已经明白:软件度量是要花费金钱和时间的,使用起来要小心、有节制。另外,软件开发在本质上与自然科学(比如物理)是不同的;相应地,软件度量在获取它们要求的东西时会不精确得多。它们是值得怀疑的——我们不能毫无保留地相信它们。

控制是出于无奈

那本书被引用得最多的是它的第一句话:“你无法控制一个不能度量的东西。”这是一句大实话,但我越来越感受到它的不妥。这句话(其实还有那本书的书名)暗示着,“控制”是任何软件项目里很重要的一方面,也许还是最重要的。其实不然!很多项目都没有引入大量的控制,但它们开展得很好,而且还产出了绝妙的成果,比如Google Earth或Wikipedia。

为了真正地理解控制的作用,你必须区分两种截然不同的项目:

  • A项目:最终花费的成本将是100万美元,而创造的价值大概是110万美元;
  • B项目:最终花费的成本将是100万美元,但创造的价值超过5000万美元。

我们的第一反应是,控制对于A项目来说非常重要,但对于B项目几乎就是无所谓的。于是,我们得出了一个奇怪的结论:严格的控制对于相对而言无用的项目意义重大,而对于有用的项目的意义要小得多。这也暗示着,你在控制方面投入得越多,你越可能在累死累活地做着一个产出卑微的项目。

在我看来,与其纠结在“如何控制一个软件项目”,我们须面对的比那重要得多的问题是:我们究竟为什么要做这么多价值不高的项目?

项目无须控制,或者只需要相对而言很少的控制——我真的可以这么说吗?也差不多吧。我的建议是,我们首先应该选择做那些不太需要精确控制的项目。然后,不管我们将如何在控制方面施力,我们必须降低对自己控制能力的期望。

一个令人不安的类比

想象一下,你正在尽力抚养一个10几岁的少年。你想要控制你的孩子,这必定让你感到有些不适。然而,你不能加大控制的力度。搞不好的话,你会彻底失败,生活也就毁了。毋庸置疑的是,你不能完全放任自流。你就像是一个正在学习握剑的剑客,应该把手中之剑视作为一只小鸟——如果握得太紧,它会受伤;如果握得太松,它便飞走了。

接下来,把“你无法控制一个不能度量的东西”这句话用到你的孩子身上。你会发现,大部分重要的东西(比如荣誉、尊严、纪律、品格、压力下的风度、价值、道德、智慧、忠诚、幽默、善良等)都是无法度量的。你必须在没有很多反馈的情况下竭尽全力去指导你的孩子。这做起来很难,但为人父母本来就不是一件易事。说起来,你可以通过学校里的成绩来获取一些度量,你还为此暗自庆幸。不过,你也知道,与孩子的西班牙语成绩比起来,他的数学成绩更能反映他的学习情况,因为对数学的掌握程度更易于度量。他在举止风度上的“成绩”更可能反映的是老师的教学水平(而不是孩子的学习情况)。

那么,怎样才能在没有控制的情况下管理项目呢?其实,你要管理的是人,而你要控制的是时间和资金投入。举例来说,你要对团队主管这么说,“我已经想好了项目的交付日期,但我现在不会告诉你。将来有一天,我会去找你,告诉你需要在一周之内结束项目。你必须时刻准备着收拾局面,把已经完成的东西打包成最终产品交付出来。你要做的工作是,以递增的方式来开展项目,根据各块功能的价值高低顺序依次叠加进主产品,持续不断地做集成、文档以及验收测试。”

我建议的应对之策听起来像敏捷方法吧。不过,如今的我已经离软件开发前线很远很远,由我来推荐具体的方法是不合适的。我所主张的是一种管理方法,它可能恰恰把团队引向了敏捷方法(至少是敏捷流派提倡的增量开发模式)。

到目前为止,我谈论的几乎都是软件工程的度量这一部分。那么,其他方面怎么样呢?我慢慢地得出这样的结论:软件工程——这个概念流行过,但现在已经过时了。我仍然相信软件值得精耕细作。但是,那与软件工程并不完全是一回事。软件工程的范畴包含一系列特定的学科,包括明确的流程、检验与走查、需求工程、可追溯性模型、度量、精确的质量控制、严格的计划与追踪、编码与文档规范等等。所有这一切都为了追求实践的一致性和可预测性。

一致性和可预测性仍然是吸引人的,但它们从来就不是最重要的东西。要知道,在过去的40年里,我们一直在折磨着自己——我们始终无法在预算之内按时完成一个软件项目。但是,正如我前面暗示的那样,这也绝不应该成为最高的目标。实际上,更重要的目标是“改革”——创建能够改变世界、或者让一个公司脱胎换骨或改变其运营方式的软件。我们在改革方面是相当成功的,但这时常发生在控制的包围圈之外。无论是现在还是将来,软件开发总是带有点试验性质的。尽管实际的软件构造未必是试验,但它的概念却是。这是我们应该专注的地方。我们原本也应该一直专注在这方面。

Tom DeMarco:软件工程这个概念已过时?的更多相关文章

  1. 解决Maven项目编译时提示:源值1.5已过时,将在未来所有版本中删除

    每次编译项目时,都提示:源值1.5已过时,将在未来所有版本中删除 查了一些资料,发现是因为IDEA默认把项目的源代码版本设置为jdk1.5,目标代码设置为jdk1.5 解决方案:  修改Maven的S ...

  2. 某些输入文件使用或覆盖了已过时的 API

    android出现注: 某些输入文件使用或覆盖了已过时的 API. 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译. 注: 某些输入文件使用了未经检查或不安全的操作. 注 ...

  3. 【转】android出现注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 注: 某些输入文件使用了未经检查或不安全的操作。 注

    使用Android studio打包应用程序出现如下错误: 注: 某些输入文件使用或覆盖了已过时的 API. 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译. 注: 某些 ...

  4. Android Studio编译OsmAnd出现警告:GeoPointParserUtil.java使用或覆盖了已过时的 API。有关详细信息请使用-Xlint:deprecation重新编译

    [背景] 之前折腾: [记录]Android Studio中导入OsmAnd并编译 期间,遇到了编译警告: 1 2 3 4 5 :OsmAnd-java:compileJava 注: E:\crifa ...

  5. 关于SVN 操作 提示文件已过时,请先update

    提示文件已过时,请先update 错误产生原因:修改文件前没有先update,从svn获取该文件的最新版本. 解决方法:备份你修改后的文件,通过Revert恢复到服务器版本后,再比较之前备份的文件,进 ...

  6. WebMvcConfigurerAdapter已过时

    Spring Boot2.0的版本(创建的时候自动选择的这个版本),然后编译器告诉我WebMvcConfigurerAdapter已过时了 @Deprecated public abstract cl ...

  7. PoI 3.17 已过时代码对比

    PoI 3.17 已过时代码对比颜色定义变化旧版本 : HSSFColor.BLACK.index新版本 : IndexedColors.BLACK.index 获取单元格格式旧版本 : cell.g ...

  8. 使用IDEA运行项目时提示:Warning:java: 源值1.5已过时, 将在未来所有发行版中删除

    如图 在使用IDEA运行项目时,在下方提示:Warning:java: 源值1.5已过时, 将在未来所有发行版中删除 这是因为JDK版本问题 解决方法如下:左上角 file ——> Projec ...

  9. ConsoleLoggerExtensions.AddConsole(ILoggerFactory)已过时代码修复

    0x00.问题 netcoreapp2.2环境下, Startup.cs 代码配置如下 public void Configure(IApplicationBuilder app, IHostingE ...

随机推荐

  1. gulp填坑记(二)——gulp多张图片自动合成雪碧图

    为优化图片,减少请求会把拿到切好的图标图片,通过ps(或者其他工具)把图片合并到一张图里面,再通过css定位把对于的样式写出来引用的html里面,对于一些图片较多的项目,这个过程可能要花费我们一天的时 ...

  2. drools 手动创建kmoudle.xml文件

    @Test public void test() { KieServices kieServices = KieServices.Factory.get(); KieResources resourc ...

  3. Java编写高质量代码改善程序的151个建议

    第一章  Java开发中通用的方法和准则 建议1:不要在常量和变量中出现易混淆的字母: (i.l.1:o.0等). 建议2:莫让常量蜕变成变量: (代码运行工程中不要改变常量值). 建议3:三元操作符 ...

  4. gcc创建静态库和共享库

    静态库和动态(共享)库静态库:编译程序在编译使用库提供的功能代码的程序时将代码复制到该程序然后编译成可执行程序,这种库成为静态库共享库:共享库比静态库的处理方式更加灵活,因而其产生的可执行文件更小,其 ...

  5. EXISTS的使用详解

    .exists的使用场合: exists 用于只能用于子查询,可以替代in,若匹配到结果,则退出内部 查询,并将条件标志为true,传回全部结果资料,in 不管匹配到匹配不到都 全部匹配完毕,使用ex ...

  6. Git提交代码到远程服务器

    1.下载Git 不用说了,这个是必须的,也是最简单的步骤,地址如下: http://git-scm.com/download 这里会提供三个版本的下载地址,读者可以自行查找. 2.创建代码库 远程的代 ...

  7. 2016-wing的年度总结

    大神们都爱写总结,为了早日成为大神,我也来写一波. 2016 有很多事情发生. 从日常生活来讲,生活水平得到了一定提升,从600一个月的村子搬到了800一个月的村子(/捂脸); 从就业环境来讲,许多人 ...

  8. JAVA中的常量定义在class中还是interface中比较合理?

    本文地址:http://blog.csdn.net/sushengmiyan 本文作者:苏生米沿 java中使用的常量可以集中定义在一个文件中. 有两种解决方案: 1.在Constants.java中 ...

  9. iOS 应用打包命令一览

    文章转载自:http://www.jianshu.com/p/5d59966eaecc 文章排版部分根据自己的理解做了一些修改. 各种命令的简介 使用命令打包iOS 应用一般会用到 xcodebuli ...

  10. 针对于Python的OpenCV环境搭建

    OpenCV 依赖 下载OpenCV 配置 总结 给Python搭建opencv的环境还真是略嫌麻烦,于是做下笔记,以备不时之需. OpenCV 依赖 opencv有些依赖,我们必须安装一下,否则接下 ...