软件开发方法需要理论
Semat计划于2009年12月由软件工程三位大师(合称“Troika”)Ivar Jacobson(UML、RUP、组件和组件架构、用例等技术之父),Bertrand Meyer(Eiffel和按约定设计之父)和Richard Soley(OMG主席)正式发起,倡导以坚实的理论、已经证明的原理和最佳实践为基础,重新发现软件工程的本质。Jacobson等撰写了三篇文章详细阐述Semat思想,本刊将陆续刊载,本文是其中第一篇。佛罗里达大西洋大学黄诗虹教授另撰有《Semat: 软件开发的又一次革命》一文,刊载于杂志官网,推荐阅读。
对于正在寻找软件开发方法的人来说,问题不在于是否能找到答案,而是确定答案是否满足要求。是的,我们已经有了很多方法——每年都会出来一茬新的,但是这让可怜的一线开发人员感到奇怪,为什么去年的招儿又不够好了,为什么他们必须接受今年的新法子。为了寻找严格的概念性论据,必须看透炒作之词,找到其中少
量行之有效的真知灼见。
在本文中,我们将论述软件开发方法学必须经历深刻的变革。应该放弃当前依赖于新词和政治式宣传的状况,转向基于理论和实验验证的严肃的科学工作。
时装业,政治还是工程学科?
软件方法学是一个特殊的领域。按原理它应该是基于科学的工程学科,但目前的实践中它却时而像时装业,时而又像搞政治。
时装业每年都要有一种新潮流,在匆忙跟风中,人们将好的和坏的一起抛弃。人们不是从自己的经验中学习,而是跟着自认为更好的走,因为其他人都说这样更好。创新者们常常抱怨,大公司拥抱变化非常缓慢,但事实上并非如此,许多大公司非常渴望尝试新事物。真正的问题在于,他们也会更快地放弃,还没等认真用起来呢,在过程和工具上的不菲投入就打水漂了。
在政治(或者说得更准确些是坏的政治)中,重点不是放在难题的切实解决,而是口号、宣传和煽情。理念不是通过对利弊仔细的讨论来提出,而是像品牌那样进行营销,借助一些大师的一些金口玉言来传播。每一种方法都试图忽略自己的同类,如果不得不承认它们的存在,通常也会恶意贬低,这弄得一线人员无所适从。
最终,很少有新思想能运用在大规模的项目里,因此对大系统开发中的质量、生产力和上市时间等等都没有产生什么影响。过去四十年中软件开发方法中出现的所有新概念里,只有少数大的创新——结构化编程、对象技术、设计模式和UML等对行业产生了真正的影响。
这些都是不成熟的表现。我们的学科该长大了。
敏捷
席卷业界的最新一波浪潮是“敏捷”。敏捷方法的确做出了许多贡献,并使我们再次注意到人在软件工程中的中心地位。一些敏捷的经验很可能仍然会在未来的方法中继续存在。与此同时,敏捷领域也为上面谈到的现象提供了活例子。作为一个重视人甚于过程和工具的运动,敏捷却提出了许多被宣传为“新的”过程和工具,而且没有说清楚其中哪些是真正新的,哪些只是已有概念的重述。很多一线人员很自然地就被弄晕了。先不说这些“新”概念的价值如何,对它们的推广方式就颇为引人注目:先是为这个方法精心编写了一份基础性文献的——一个宣言(http://agilemanifesto.org/),更多的是第一人称复数的情感诉求(我们必须……),而缺少事实依据。这种风格对于吸引眼球可能有效,但随着概念日益成熟,还是应该采用更传统(也更枯燥的)阐释形式。
在工程和科学中,一种新技术的提出者与任何人一样都急于推广自己的发明,但是也会很小心地确定应用这项新技术在什么地方存在不足或者未经证实。然而,很少有软件方法学者会提供这样的警示信息。太多人夸大了自己的方法与前人的差异。每一次变革(比如对象技术)中,有多少突破其实是已知概念的调整?逐渐改进当然没有错,科学和工程中大量进展都是如此实现的。但是,将每一次改进都包装成革命,就没意思了。
目前的方法:多种实践的大杂烩
我们目前软件开发的方法,无论是商业还是公司内部,新还是旧,需求已知还是不清,实际上都只是来自方法文献中各种元素的组合,加上一些特定于领域或者业务的扩展。基本的成分是一个个实践。
如果我们将这些基本成分从大杂烩中分离出来,大家就可以建立自己所需的方法。这种方法是以模块的方式设计的,能够在不断总结经验的基础上快速演进,响应我们快速变化的行业的需求。
构建理论
经济压力是当前的时代特征,与时装业的跟风和政治宣传一样都不会完全消失。但是,所有关注软件工程价值的方法学者都理应为学科找到存在的理由。
我们所缺乏的是作为一门科学和工程学的基础:理论及其验证。我们应该采取以下步骤,将软件方法学转变为一种严谨的工作。
对方法的本质进行建模
软件开发是一种人的活动,但它也是由若干明确定义的步骤组成的,而且我们对这些步骤之间关系已经有了充分认识。至少,在有经验的从业人员脑中,对这些概念的定义和理解都是不言自明的。但这还不够,我们需要坚实的软件开发理论。形式化方法为我们提供了进行建模的正确工具,含有约定构造(contract)的面向对象语言也可以实现同一目的。如果软件开发的任务和限制没有精确的、无歧义的模型,我们就无法显著地进行改善。模型应该独立于具体方法(只描述问题,而非解决方案);模型应该不仅包含定义和公理,而且还应该包括描述所有系统和可行方法的定理——这恰恰是形式化模型经常缺失的部分。
寻找内核——所有方法之母
所有方法在被过度宣传的差异之外,都有许多共同的属性。而以理论作为基础,我们将描述出任何有效的开发高质量软件的方法都应该满足的属性。毕竟,它们都是用来开发软件的,而且都承认软件开发中有一些东西总是需要。我们总是要写代码,用某种方式进行测试,总是要考虑需求(无论要不要文档),总是有backlog(无论显式还是隐式),总是需要计划(无论是写在纸上,还是留在脑子里)。
我们需要找到软件开发本质的不能再简化的内核(Kernel)。例如,通过研究大约50种方法包括XP和Scrum,我们已经找到了一个包含超过15个元素的内核,其中的元素是我们总要做的事情或者总要生成的东西。
使用内核描述各种有价值的方法
有了内核之后,所有方法都可以进行描述和比较。我们可以从所有广泛使用和经过验证的方法或者过程中采集隐含的实践,比如架构、组件、迭代等等。有些实践是重叠的,比如用例驱动开发和特性驱动开发。有些是互相补充的,比如用例驱动开发和按约定设计。
内核清除了方法之间表面存在的差异,比如不同方法中只是称呼不同的相同事物。比如,RUP所说的迭代在Scrum中称为sprint,但是它们基本上说的是一回事。通过这种清理,可以明显地看出不同方法之间真正的差异。
因为内核对于任何具体的实践都是中立的,我们可以简单地分辨出不同实践之间的实际区别,不是表面上的,而是深层次的。这将减少各种方法中包含的“宗教”成分。
行动起来!
本文是一篇行动呼吁书,我们希望它能够被所有同意软件业应该进入成熟阶段的同仁所接纳(当然,还需要进行适当的修订)。
最重要的一步,可能是认识到不同学派应该求同存异。具体而言,要认识到以下两点。
敏捷与过程:这两者之间的差异被夸大了。它们的目标其实是一样的:流畅地开发出优秀的软件。所有过程都需要敏捷,因为与其他领域相比,软件中变化是规则,稳定则是例外。与此同时,所有敏捷方法如果要应用于关键的企业项目,还是需要过程,包括规格说明和设计。
形式化与非形式化:软件开发人员必须认识到,任何进展都会多多少少包含一些形式化方法,没有必要畏之如虎。所有工程都要依赖数学:我们能够想象电气或者机械工程师不愿意学习和运用数学工具吗?形式化方法当然有其局限——没人说它们能解决任何问题,但是形式化方法绝不是纯理论,它们的价值早已经被不断证明了。无论我们是否能认识到这一点,它们都已经在一些领域(现代编程语言中的类型检查就是一种证明形式,而硬件设计也越来越依靠数学工具)广泛应用了。随着IT业向更专业的运营方式发展,有选择的数学工具的运用将与日俱增。
仅仅通过忽略表面上的差异,并充分利用已有的概念,我们将能够为业界提供曾经只能从专家们那里得到的东西:科学上坚实、而且实用的方法和工具。
这就是我们的看法。我们是否像堂吉诃德那样在挑战风车呢?还是有可能就此对现在开发方法中混乱的局面正本清源,开发出业界所需要的坚实基础?有一点是肯定的:进步只能来自许多人的通力合作。已经有许多论坛在讨论这些问题,请从我们的博客(http://ivarblog.com/, http://bertrandmeyer.com)开始。欢迎将你的想法告诉我们,帮助软件工程学科进入成熟阶段。