Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。
几年前,我研究过算法及其复杂度问题。这个领域特别的清晰,每一个概念都被清楚的定义,每一个结果都建立在先前的证明上。当你研究这个领域的时候,你完全可以放下心来,你所学的东西都与数学严丝合缝。即使是像近似算法和概率算法这样不是很完美的结果,人们也对它们的缺陷进行了严格的分析。计算的科学中的其他领域,例如网路拓扑学和密码学也同样处于这样一种令人感觉完美的状态。
现在,我从事软件工程领域,它则没有那么清晰。没有哪个概念是被精准定义的。结论中充满了“通常”或者“一般”这样的字眼。目前的研究对将来可能有帮助,也可能没有帮助。新的方法经常推翻旧的方法,然后火上一阵子后便会由于其局限性又慢慢变的过时了。人们曾经认为结构化编程是究极答案,随后转为第四代编程语言,接下来是面向对象编程,然后是极限编程,现在可能又变为开源编程。
软件工程就像是战壕里的士兵。很少多少人仅仅因为这个问题中蕴含的美就去关心 P/NP 问题。计算机领域就是利用计算机来处理问题,这意味着我们需要编写程序来解决实际问题,然后在一台机器上把程序跑起来。根据邱奇-图灵猜想,所有的计算机硬件都是等价的。所以当新的计算机架构确定后,计算机科学真正的挑战在于编写软件。我们需要这样的软件,它能在有限的时间和预算内,完成我们期望的工作,并且尽可能少出点问题。
虽然有了这样一个目标,但是依旧有些问题困扰着我(也可能困扰着其他研究人员),那就是为什么软件工程不能像其他的计算机领域一样,存在更加精确严格的结论。换句话说就是,有多少软件设计和软件架构能够被正规化、流程化?图 1 为我们回答了这个问题。
图 1. 计算机科学中的分割线
红线上面的话题构成了软件工程,红线下面的话题构成了计算机科学。后者的话题具有清晰的且正式的结果。对于计算机科学领域的开放性问题,我们希望新的结论也能够有正式的规定。这些领域彼此之间也是相关的,例如密码学基于复杂度,编译器基于算法学。更重要的是,我们相信这些领域中已经存在的结论将永远是真的。
那么,那条红线是什么呢?为什么没有一个关于软件工程的话题位于其下方?这条线是指一种属性,一种直接涉及人类活动的属性。软件工程具有这种属性,而传统的计算机科学则没有这种属性。人们可以利用那些位于红线以下的学科的结论,但是这些结论并不以人的意志为转移。
软件工程有一个必不可少的部分,那就是人。例如,软件的可维护性是指人类去理解、发现并修复 Bug 的能力。软件的可维护性也许会受到一些正规的计算机科学概念的影响,例如软件控制流图的循环复杂度。但是其主要还是受人类的影响比较多,受限于人们理解其源代码意义和目的的程度。像一个软件系统是否具有很好的可维护性这样的问题,是不能仅仅靠机器测试来回答的。
同样的情况适用于软件安全性问题。研究人员使用了一些正规的方法来研究软件系统对人类健康和财富的影响。但是在测试的系统中,不考虑人类的这一组成部分的软件安全性研究不是完整的研究。我们可以想出各式各样的面谈技巧,以便从软件需求者那里获取准确的要求,并且我们可以创造出多种符号系统来记录我们所了解的东西。但是不论在这方面有多少研究都改变不了一个事实,那就是需求收集经常涉及到与人的交谈或者观察人的行为。有些时候人们跟我们说实话,但是有些时候并不会。有些时候人们可能会为了别的原因而撒谎。有些时候人们可能会真诚的回答问题以便给我们一些正确的信息,但是有些人并不会这么做。
综上所述,我们可以得到康奈尔观点(Connell's Thesis):
“由于人类活动的原因,软件工程永远不可能成为一门严格的科学,并带有经过实践检验的真理。”
这是一个关于正式(软件)系统局限性的超数学论断。我没有为这个论断提供证明,也没有任何证据能证明它正确。但是事实依旧,软件工程的核心问题也是人类所关注的问题:
1 这个软件应该用来干什么?(需求性、可用性、安全性)
2 软件的内部是什么样子的,是否容易修复或者修改?(架构问题、设计问题、可测量性,可移植性,可扩展性)
3 软件开发需要多久?(预算问题)
4 如何进行软件的开发?(编码问题、测试问题、测量问题、配置问题)
5 如何组织团队以便高效开发?(管理问题、流程问题、软件文档)
以上所有的问题都跟人相关。
本文阐述了为什么软件工程如此的困难和模糊。试验似的方法可能对某个团队的程序员管用但是对其他的团队就不适用了。对过去工程的详细分析可能不会对下个编程项目起到很好的作用。每一个具有革命性的软件开发工具都有助于开发,但随后便只是夸夸其谈空有虚表。究其原因在于人类本身就是易变的,遇难而退的,不可预测的。
在我抛砖引玉前,我想先说说三种可能的反对意见:
“这个观点(Connell's Thesis)只是可以自圆其说而已,只要软件工程的某些领域能够被严格的解决,人们就可以重新定义软件工程,从而避免人为因素的干扰。”
这个反对意见有一定的正确性,但是也有其局限性。我敢肯定,那些通常被称为软件工程的学科将继续从本质上不服从所谓严格的解。从局部来看,一些问题可能存在正式且严格的解决办法,但是我认为这种的严格解仅仅只存在于软件工程中心问题的边缘地带。
“软件工程中的概率论结果已经反驳了这一观点。”
像功能点计数问题(Function Point Counting),第二代构造性成本模型(COCOMO II),PROBE 方法 和其他方法一般是用来解决估算问题的。尽管他们都以数学的形式出现,但是这些方法并没有被证明或者有一个正式的结论。统计学方法是对旧软件项目中人类经验进行量化的一种尝试,然后将从这些数据得到的结论推广到未来的工程项目中。这个方法有时候会顶用。实际上,这些看似有严格数学公式的方法只是徒有其表,做做样子罢了。例如在 COCOMO II 中有一个数学公式:PersonMonths = 2.94 × SizeB ,其中 B = 0.91 + 0.01 × Σ SFi ,而 SFi 是五个主观影响因素,例如“开发的灵活性”和“团队的凝聚力”。这个公式看似严谨,其实不然,里面掺入了人为的影响因素。
“正规的软件工程过程就像净室软件工程(cleanroom engineering)一样,是为一种为软件开发而不断寻找严谨的、可证明的方法的过程。这些过程正在抬升图 1 中的那条红线并不断的吞噬先前那些模糊的软件工程的主题。”
确实,那些正式的软件研究人员正在各种问题上取得进展。但是他们同样栽倒在第一种反对意见上:他们在一个狭隘的角度上定义软件开发,从而使得软件工程中存在有严格的解。形式化的方法抹平了那些以人类为中心的问题。例如,正规的软件开发方法都试图去得到一个严格且明确的软件规范。然后使用这个规范去驱动(和证明)下一个环节的软件开发。一个正规的方法也许确实包含了一个明确的文字说明方案,但是没有一个正规的方法能够确切的描述出人们心中那种模糊的想法,也就是想要用软件做什么。
和这些反对意见相反,我想说的是,软件工程完全不同于传统的、正式计算机科学。前者依靠于人而后者并不需要。我们可得出康奈尔推论(Connell's Corollary):
“我们不应该再试图去证明软件工程中的那些基本结论,要接受这个领域中那些即将成为一般准则的重大进展。”
举个例子,戴维·帕纳斯(David Parnas)在 1972 年写了一篇非常出众的论文:“On The Criteria To Be Used in Decomposing Systems into Modules”。在这篇论文中,帕纳斯描述了一个简单的实验,提出来可选软件设计策略,一部分用于隐藏信息,另一部分则公之于众 。基于这个小实验,他得出了一些结论并给出一些建议。在这篇论文中,没有任何证明,帕纳斯也没有声明能够保证实验的可重复性。但是这篇论文却蕴含哲理并且对面向对象语言的设计产生了巨大的影响。
另一个例子是著名的卡耐基梅隆大学软件工程研究所关于 CMMI 的大量工作。CMMI 起先只是一个是软件开发模型,现在已经成为一个包含各种各样的其他工程的项目。CMMI 大概有 1000 页的资料,是一千多人一年的工作量,这其中还不包含基础内容,解释部分和训练材料。它被许多大型的组织机构使用,并且显著改善了他们的软件开发和产品。但是 CMMI 没有包含任何永恒的结论。它仅仅只是一系列关于如何组织软件工程项目的建议,这些建议基于以往的软件开发。事实上,(卡耐基梅隆大学)软件工程研究所指出,CMMI 甚至不能称之为一个完整的软件开发,它只是一个基本的开发,里面充斥着了每个组织的详细开发信息。
像模式设计、体系架构、基于错误的重构、敏捷开发和数据可视化这些领域同样存在这样的情况,在这些领域中,部分工作可能会包含先前的结论,但是其最终的目标是形成一个以人类行为为基础的系统。简单来说就是计算机科学的核心领域(在红线一下)是软件工程的重要工具。在设计高性能的应用软件时,很有必要去了解算法的前世今生。排队论有助于设计操作系统的内核。净室软件工程中的一些方法则在某些领域中非常有用。以往的经验总结有助于相同的团队完成相似的任务。但是对于软件工程来说,公式化只是一个必要条件而不是充分的条件。为了说明这一点,可以类比结构工程与现实建筑(房屋和建筑)。
想象一个非常有才的结构工程师,他是建筑材料、应力与应变、载荷分布、风切变、抗震强度等方面的世界级专家。每个国家的建筑师在对一个项目进行设计与构造之前都会拜访一下这个人。但是这个神话一般的结构工程师真的会有助于你去设计建筑吗?一点都不会。我们的结构工程师可能乎善于与客户进行交流,从而没法设计出人们喜欢居住的房间,也无法想出解决问题的新办法,同时也缺乏审美观念。结构工程有助于现实的建筑,但这对于好的设计来说它是不够的。成功的架构应该集创造性、远见性、多方位思考和人性化于一身。
同样的道理,经典的计算机科学有助于软件工程,但却远远不够。好的软件工程也是集创造性、远见性、多方位思考和人性化于一身。这一结论有助于软件工程的研究者们放飞自我,从而将更多的精力放在应该做的事情上——为未来的软件工程师们建立一套收集智慧机制。我们不应该试图将软件工程扩展为以数学为基础的计算机科学。那是完全没用的,并且可能使我们离待发现的进展愈行愈远。
致谢
感谢史蒂夫·霍默(Steve Homer)与我进行讨论,从而使得我对这个问题很感兴趣。
英文原文:http://www.drdobbs.com/architecture-and-design/software-engineering-computer-science/217701907
译者:无