软件开发的轻与重

重意味着严谨、繁琐,轻则意味着迅捷、零散。应当轻还是重?这是个问题

通过这次的阅读任务,我想从这两个方面谈软件工程的轻与重:开发流程模式 与 开发团队模式

开发流程模式的轻与重:

Managing the development of large software systems: concepts and techniques

理想的瀑布模型:

系统需求——>软件需求——>分析——>程序设计——>编码——>测试——>运行

an implementation steps to develop a large computer program for delivery to customer

这个模型是如此简洁,以至于我在上大学后很长一段时间就认为这就是软件开发唯一的模式(在长期地独立进行小型结构化编程训练)。事到如今,我固然意识到了我的图森破,瀑布开发模式已不再适用于大部分软件的开发,但其中原因并不那么简单,这些原因也在向我们展示着软件工程不同于人类其他工程模式的特点,给从事软件开发的我们以启示。

早期的瀑布模型可归为软件开发工程方法(engineering methodologies),这种模式的特点是将设计与实施一分为二,这种思路在其他工程领域是理所应当的,如果建设者在建造桥梁过程中同时进行施工和设计是不可想象的。然而,软件开发过程事实上的确有很多不同之处,当开发团队正在编码时发现需求分析工作有所缺陷(这在软件开发中是非常常见的),他们不得不重新做需求分析、修改之前的设计、进而修改代码。如果来自瀑布上层工作的缺陷仅仅带来下层的修改工作应该说是很幸运的了,如果开发团队笃信工程方法,他们不认为导致他们返工的意外情况会不时出现,他们会及其严谨地按照当前及其严密而步骤清晰的设计来实施(这就是常见的工程模式)。如果当他们大功告成时发现他们的产品不符合用户的需求,那么恐怕就是前功尽弃,要推倒重做了。由此,瀑布模型又衍生出了一些变化的版本,如不同步骤间具有交互的模型,但即便如此其模式仍显得古板,而且需要大量文档的支持。随着软件工程方法的不断实践,这个重量级的办法在大多数软件开发过程中越发显得笨重而低效。

The New Methodology

Most software development is a chaotic activity, often characterized by the phrase "code and fix". The software is written without much of an underlying plan, and the design of the system is cobbled together from many short term decisions. 

在非正规的软件开发过程中,上述这种情况是很常见的。code and fix应该是最早的软件开发模式,工程模式是它的后来者,而两者互相之间并不能取代另一方。code and fix 对小型项目很管用,但对于大项目来说会导致系统的混乱以及调试困难。工程模式使得大型软件项目开发变得严谨有序,但是软件开发的特性决定编码的时候总会出现总体设计考虑不到的问题,局部的code and fix是难以避免的。这种超轻量级的开发模式虽无章法,但暂且算一种“方法”。

敏捷型方法(agile methodologies)的发展是对这些工程方法的反叛。 对许多人来说,这类方法的吸引之处在于对繁文缛节的官僚过程的反叛。它们 在无过程和过于繁琐的过程中达到了一种平衡,使得能以不多的步骤过程获取 较满意的结果。

敏捷型与工程型方法有一些显著的区别。其中一个显而易见的不同反映在文档 上。敏捷型不是很面向文档,对于一项任务,它们通常只要求尽可能少的文档。 从许多方面来看,它们更象是“面向源码”(code-oriented〕。事实上,它们 认为最根本的文档应该是源码。

但是,我并不以为文档方面的特点是敏捷型方法的根本之点。文档减 少仅仅是个表象,它其实反映的是两个更深层的特点:

  • 敏捷型方法是“适应性”而非“预见性”。 工程方法试图对一个软件开发项目在很长的时间跨度内作出详细的计划, 然后依计划进行开发。这类方法在一般情况下工作良好,但(需求、环境等) 有变化时就不太灵了。因此它们本质上是拒绝变化的。而敏捷型方法则欢迎 变化。其实,它们的目的就是成为适应变化的过程,甚至能允许改变自身来适 应变化。
  • 敏捷型方法是“面向人”的(people-oriented) 而非“面向过程”的 (process-oriented)。 工程型方法的目标是定义一个过程,不管是谁用都工作。而敏捷型方法 则认为没有任何过程能代替开发组的技能,过程起的作用是对开发组的 工作提供支持。

软件开发的特性,不完全的总结如下:

1.设计工作与实施过程难以分离,软件开发本身是创造性的工作而不是重复性的工作

2.具体操作(编码)过程会出现很多难以预计的问题

3.面向各个不同应用领域的软件需要应对各种不同的需求,需求分析人员缺乏软件开发专业知识,开发团队也不了解应用领域的知识,需求分析在软件开发过程中是递进地、不断完善的

4.软件本身实质上仅仅是代码,代码是灵活的,修改代码的代价较小(相对土木工程等),同时测试版本很容易实现。没有什么比软件本身更能向人展示、说明产品情况的了

基于以上特性,新方法学提倡:迭代式的开发模式以应对长远计划的困难,将软件设计与编码结合,不停地发布测试版本同时完善需求;适应性的客户,客户必须适应这种非一次性计划的模式,与团队保持紧密联系,及时地给予回馈,并相信开发团队能够保质保量完成工作;以人为本的管理理念,软件开发是创造性的,开发人员应当是高素质、自觉地,工作应由术人员负责管理而不是领导,由业务专家提供指导建议。

敏捷型方法不仅尊重软件开发的特性,也受到技术人员的欢迎。在开发流程的轻与重之间,敏捷型方法趋于一种平衡。作为不断发展的新方法,这是一种模式上的突破。

开发团队模式的轻与重:

Cathedral and the Bazaar

当开源运动"如火如荼"的进行之时,我还是个小学生。如今浪潮已经过去,我只能凭借资料和脑补想象那种盛况了。

<<Cathedral and the Bazaar>>作者 Eric S. Raymond 基于他对linux内核开发过程的观察和开源软件项目的管理经验,提出了19条开源开发守则。尽管此书在开源工作者之中广泛流传并备受推崇,但开源开发至今仍显露出众多问题。

所谓质量,只有在某人对它负责时才有意义,而这个“某人”只能是一个人,不能是几个人——二重奏除外

                                              ——Frederick P. Brooks

Lost in CatB

当开源带来极高的生产率的同时,软件的质量也遭到严重的破坏。Raymond认为开源意味着更多开发者,更多的开发者意味着更少的bug能够溜掉,从而提高软件的质量。然而正如上面这句话所说的,实际情况是,如果一个有bug的程序到了10个开源开发者手中,也许会有7个人发现bug,其中5个人会修改(俩人放弃),1个人会上报给程序的提供者完善程序,而剩下3个人用它写出了依然有bug的程序并流传到更多人那里。

开源虽然创造了史无前例的全民编程热潮,但也导致了无责任、非专业、凌乱的软件开发。在浪潮退去后,传统的紧密联系的团队开发,依然是现在软件开发模式的主流。

在开源的轻与传统的重之间,似乎还没有像敏捷性方法在开发流程上取得成功那样有一个比较完美的平衡点,或许android可以算是一个正面例子,但开源仅限于应用层面,系统开发仍然是传统、封闭的。

big ball of mud

大泥球发生的主要原因可以归结为:

  1. 一次性代码
  2. 碎片式增长
  3. 为了让软件不出问题
  4. Copy/paste导致问题转移(有问题的代码被复制到很多地方,不断蔓延)

大泥球之罪的根源可以说就是code and fix,如果 code and fix 是无法回避的,那么大泥球也无法彻底规避。然而,有责任感、专业的技术人员能够帮助减少泥球。

No Silver Bullet - Essence and Accidents of Software Engineering

软件产业为什么没有像我们的计算机硬件、工业产品那样在近几十年里生产率翻了数十番,从渴望不可及到走进千家万户,这是此篇文章讨论的核心问题。

作者Brooks认为,附加性的困难会随着工具的改善而逐渐淡化,反而是本质性的困难最难以解决,因为大部分的活动是发生在人们的脑海里,缺乏有效的辅助工具。依造Brooks的说法有下列几项:

  • 复杂性(complexity):软件要解决的问题,通常牵扯到计算步骤,这是一种人为、抽象化的智能活动,多半是复杂的。
  • 隐匿性(invisibility):尚未完成的软件是看不见的,即使利用图标说明,也常无法充分呈现其结构,使得人们在沟通上面临极大的困难。
  • 配合性(conformity):在大型软件环境中,各子系统的接口必须协同一致。由于时间和环境的演变,要维持这样的一致性通常十分困难。
  • 易变性(changeability):软件所应用的环境常是由人群、法规、硬件设备、应用领域等,各因素所汇集而成,而这些因素皆会快速变化。

Brooks对银弹寄希望于实现现代设计与模块化概念的特征的程序设计语言(如Ada)和面向对象程序设计技术,但如今事实证明这些并没有解决软件工程生产率面临的基本问题。对很多人而言,编程的创造性正是吸引他们的地方,但如果软件开发仍然是一件创造性的工作,而创造与实现两个步骤难以分开(如在上文软件开发特性中提到的),那么其生产率的低下就是不可避免的。

自动化的软件开发是银弹的终极形式,但实现的方法仍遥遥无期。不过我相信终有一天,软件开发能够像编译工作一样,由少部分专业人士的努力彻底解放软件生产力。

posted on 2012-11-14 11:35  百年coding  阅读(2075)  评论(5编辑  收藏  举报