软件的定义

image.png
软件 = 程序 + 数据 + 文档,即软件是有程序、数据和文档构成的,其中:

  • 程序:即计算机可以接受的一系列指令,运行时可以提供所要求的功能和性能。
  • 数据:使得程序能够适当地操作信息的数据结构。
  • 文档:描述程序的研制过程、方法和使用的图文资料。

软件的本质特性

软件的行为只有通过程序的运行才能呈现出来,换句话讲,只有在程序运行的过程中才能观察到软件的功能和性能,而软件提供的信息和服务,又融合了其所在行业的业务领域知识,从这个方面来看,软件更像是嵌入式的数字化知识,这种知识载体的特征,对软件开发带来了什么样的影响呢?

image.png
飞机和软件都是人类的创造物,飞机是有形的物体,一架大型的飞机由数百万个单独的部件组成,需要上千人组装,但是通常都能够按时按预算交付使用,软件是人类思维的创造物,微软于1989年11月发布的Word1.0版本,这个软件大概有25万行的源代码,但是开发软件却花费了整整55个人年,一再地推迟交付,比原计划晚了4年,直观上来看建造大型的飞机似乎要比开发一个简单地Word软件要复杂得多,但实际情况却大相径庭,由此引出我们的疑问,开发软件与建造客机有什么本质的区别?

image.png

软件工程领域非常有影响力的人物Fred Brooks教授在1987年发表了一篇题为“没有银弹”的文章,文章中指出软件具有复杂性、一致性、可变性和不见性等固有的内在特性, 这是造成软件开发困难的根本原因。软件是人类思维和智能的一种延伸,它比任何以往人类的创造物都要复杂得多。
image.png

复杂性

image.png
上图是一个Linux内核的复杂网络图,它的节点代表函数,它的边代表函数的调用,但是这个图形也仅仅表示的是函数之间的静态调用,而在动态运行过程中系统会呈现出更为复杂的状态,很难用图形进行描述。

image.png
如今我们已经进入云计算时代,在互联网的集群环境下系统规模更大更复杂,像Google的搜索引擎、亚马逊的云计算中心以及阿里云等,其规模都超过了百万台服务器,可以说软件是人类创造的最复杂的物体,而这种复杂性会给软件开发管理和质量保证带来很多困难。

一致性

软件开发的另一个特点是人为设计带来的复杂性,软件必须遵从人为的惯例并适应已有的技术和系统,随着接口的不同而改变,但是这些变化都是人为设计的结果,可以用心所欲、毫无规则来形容。
image.png
拿微信来说,用户使用不同的终端发出服务请求,微信服务器接收请求并把它们转发给一个抢票的主服务器,该主服务器处理响应要求很高的抢票请求,而其他请求则转发给辅助服务器,当然在整个过程中,系统还会和其他诸如身份认证等系统进行交互,这个抢票应用需要通过与微信系统、身份验证系统等打交道,因此必须遵从这些系统定义的接口,而这些接口都是软件工程师人为设计的,任何接口的变化都会带来微信应用的修改,所以说要保持与其他系统接口的一致性,也会造成软件设计的复杂性。

可变性

我们经常听到这样一句话“这个世界在变,唯一不变的是一直在变”,通过微信的演化历史来看一下软件的可变性。
image.png
微信于2010年11月正式立项,2011年1月和3月分别发布了1.0和1.2版本,实现了文字短信和图片分享功能,但是当时市场反应冷淡。2011年5月推出语音通信功能发布了2.0版本,微信开始快速地流行和传播。2011年10月提供了“查看附近的人”功能,该功能成为微信用户增长的一个爆发点。2012年4月发布4.0版本,退出了朋友圈、视频通话及微信公众平台,开始建立手机上的熟人社交圈。2013年8月,5.0及后续版本提供了支付、表情、游戏等一系列贴近用户生活的服务,并专门开辟了服务号,打造一种更具体验效果的移动互联网生活方式。这个事例告诉我们,软件只要是使用就会一直在变,而这个改变是随需而变

image.png
相对于建筑和飞机等工程制品来说,软件的变更似乎更加频繁,这也许是因为建筑和飞机修改成本太高所致,人们总是以为软件很容易修改,但是却忽视了修改带来的副作用。如上图所示,理想的情况下随着软件的使用,其故障率会逐渐降低,逐渐达到一个稳定地质量,但是软件是在不断变化的,每一次的修改都会造成故障率的升高,同时也可能给软件的结构带来破坏,不断的修改最终可能导致软件发生退化从而结束其生命周期。尽管如此,成功的软件都是会发生演化的,没有任何变化的软件一定是没有用的,虽然软件的可变性给开发带来了很多难题,但也给软件本身带来了生命力,所以要用积极地态度和有效地方法来控制变更,使软件在演化过程中保证高质量。

不可见性

image.png
软件还有一个特性就是“看不见”“摸不着”。像建筑、飞机这些有形的物体,我们可以用平面的图形抽象出其结构形态,但是软件是逻辑的,没有空间的形体特征,因此缺少合适的几何表达方式。开发人员在接收到用户需求时,整个开发的过程只能看到源代码,而代码并不是软件本身,因此在开发完成之前很难看到软件是如何执行的,这种不可见性不仅限制了软件的设计过程,同时严重地阻碍了相互之间的人与人的交流,从而对开发过程的管理造成很大困难。

image.png
Brooks教授在著名的《人月神话》一书中把软件人员形容成“皇帝的新衣”故事里的裁缝,开发人员一直在编织却看不到编织的织物,最后也许是编织出来一堆无用的废物,或者什么也没有做出来。

总结

复杂性、一致性、可变性、不可见性等特性是软件的本质特性,这些特性使得软件开发 过程变得难以控制,因此我们需要寻找解决问题的有效方法,从而保证软件开发过程的高效、有序和可控。