简述软件工程的历史演变
软件工程的历史演变要从软件发展,软件过程的发展和软件工程管理这三个角度去说。一方面,随着软件的快速发展,出现了许许多多越来越难以解决的问题,为统一地回答和解决这些问题,催生出了软件工程。另一方面,从软件工程中衍生出了软件过程和软件工程管理的概念,它们都是为了解决软件系统开发中的本质困难而诞生的。前者目标是更好地解决问题,而后者的目标则是为了复制成功经验。无论为解决开发软件系统的困难而产生的学科会发展成什么样,它们的核心目标都是解决软件系统开发中的不可见性,复杂性,可变性和一致性这几个本质困难的。下面将就软件发展的历史阶段来说一说这些困难是怎样逐渐增大的以及与之对应的软件过程的演变。
软件发展的第一个阶段是软硬件一体化阶段,即软件开发要从硬件考虑,根据硬件情况去设计软件。产生这个阶段的最主要原因是硬件性能的限制。这一阶段主要使用的是硬件,用硬件做到一些之前只能全凭人脑才能做的事。软件几乎完全绑定与特定的硬件,无法迁移和复用,因此也就无法做更多的应用,对软件的想象力被局限在了硬件。对于软件开发团队来说,也局限在了小作坊和“个人英雄主义”的形式。当然在这一阶段,随着硬件的发展和伴随的软件复杂度的增高,人们逐渐发现了目前所采用的粗糙的软件开发方式“编码加改错(code and fix)”的问题,也出现了类似硬件开发过程的软件开发过程SAGE等。但失败的软件项目的还是在增多,因此才催生出“软件工程”的概念。
第二个阶段是软件成为了独立的产品。进入到这一阶段的最主要的原因是软件不再局限于硬件,高级语言的出现使得一个平台上的软件同样可以运行在其他平台,同时个人计算机的出现使得大量的公司开始开发软件为个人计算机用户服务。由于需求的空前增长和可迁移性,这一阶段的软件开始出现了爆发,这种爆发不止是软件产品数量上的,更是软件规模上的和占计算机系统产品比重上的。这一阶段的软件产品展现出了远胜之前的复杂性,可变性,在此基础上想保证一致性也更加的困难。与之对应的这一时期的软件过程也有了很大发展,其一是形式化方法,意图从数学上找到一个一般性的方法,一劳永逸地指导复杂软件系统的开发问题。其二是结构化程序设计的思想,通过对程序划分模块,能将复杂的问题转化为简单的问题去解决。还有就是经典的生命周期模型“瀑布模型的出现”,让软件开发过程第一次有了一个比较有效和完善的指导方案。但是这一时期诞生的方法还存在着许多问题,形式化方法能应用的领域太狭窄,使用瀑布模型开发软件系统效率太低,而且还缺乏对软件质量的评估和提升的方法。所幸在这一阶段又出现了面向对象开发技术,它极大地改变了软件过程,直面软件开发过程中不可见性、复杂性、一致性和可变性的问题,提供了套编程范式,并在此范式上产生了一系列的编程语言,框架,设计思想等等技术,它们同样具备更高的开发效率。同时,也出现了以 CMM 为代表的软件过程改进模型等。
第三个阶段的发展特征是网络化和服务化。这一阶段的到来除了软件进一步发展之外,主要是因为互联网和移动互联网的出现,极大地增加了用户规模和软件产品的使用方式,对软件产生了额外的要求,这就不可避免地又增加了软件复杂度。同时,由于竞争的需要,需求不确定性和系统的快速演化成为一个日益突出的问题。最后,软件分发和使用方式也出现了显著的变化,从拷贝复制逐渐过渡到基于网络的服务乃至云计算的形式,使得软件系统的版本更迭时间有了大为缩短的潜力。这些新情况的出现,使得软件开发的四大本质难题中,可变性和一致性对软件开发的影响更为突出,因而也催生了整个软件过程历史上最为纷繁的一个时代,大量的软件过程在这个阶段涌现出来。其中最具代表性的是一系列具有迭代式特征的开发方法,比如增量模型,螺旋模型和原型法等,这与之前的单一过程有很大区别。但是这些还不够,大型软件开发过程正逐渐地被视为一个交流和学习的过程,而迭代式的开发只是遵从这一规律,而并没有完全从这一过程本身出发去考虑,因此又出现“敏捷”开发方法,一系列以此为指导思想的方法诞生了,它们被统称为“敏捷方法”,比较著名的有SCRUM,XP和 Kanban 等。在敏捷方法之后,还有着开源软件方法,这是一种基于并行开发模式的软件开发的组织与管理方式。这种方法依赖于分散在全球的开发者和使用者的协作,而只有 Internet才能为这种大规模协助提供交流沟通的工具。廉价的Internet是开源软件得以发展的必要条件。
到了现在,随着互联网应用的日益普及,用户对软件系统和服务提出了更多的要求,“多快好省”已成为大多数互联网时代软件用户的基本期望。具体而言,功能要丰富、更新要及时、要稳定可靠,同时用户获取服务的成本不能过高。所有这一切,都使得人们对软件产品和服务的需求与软件产品和服务的开发能力之间越来越不匹配。DevOps 因此产生了,它足以胜任需求很难确定,需要快速响应变更,需要快速提供价值,需要高可靠性、安全性的当下互联网时代对软件的要求,同时又进一步解决了之前提到的软件开发的本质性难题。
从软件发展及对应的应对软件开发遇到的困难的学科——软件工程的发展,我们可以看到一些非常有意思的特点。
第一,软件工程中提出的方法总是落后于问题的出现,和自然科学可以用来预测一些事情的发生不同,软件工程总是总结成功和失败的经验并提出一套方法去避免你犯错而不是去预测问题的出现并提前提出解决方法,这是目前的特征。
第二,软件工程所关注的对象不仅局限于技术——即用于控制和管理复杂度的技术,还在于人,因为软件工程任务并不是由一个人完成的,人与人之间的交流也是复杂度的一部分。甚至是,它还占主导地位。因此,除了软件过程外,还有软件工程管理,包括软件项目管理和软件过程管理,它们将人视为重要因素,已经属于管理学的范畴了。在软件工程发展的过程中,管理所占的比重是逐渐加大的,可以预见在未来,管理和技术在软件工程中也一定会共同发展下去。
第三,关于软件的知识将会越来越容易让人理解和更为广泛地分发,高级程序设计语言、框架技术和设计模式甚至与开发范式不但可以提高开发效率,更有助于理解一个大型项目。同时,互联网和开源软件的存在也为软件知识的学习和分享提供了便利。这同样也是有助于我们理解和管理复杂度的。还有迭代式开发方式的经久不衰也能印证这个观点,因为迭代式的方式符合人的认知规律,相信在未来这也将一直是主流的方式。
总览软件工程历史的演变,无外乎在解决两方面的问题,一是软件开发本质上的困难,再就是时代的发展中对于软件系统更多的要求。一个好的软件过程或者是软件工程管理方法一定是同时在这两方面有较大进展的。我们无法一劳永逸地解决软件开发本质上的困难,但可以知道一部分软件未来发展的方向,这样其实就可以为软件工程学科发展提供目标了。