要想软件“软”,预算不能“硬”

2018-12-23

Rober C. Martin 在《Clearn Architecture》一书中提到软件在两方面的价值:行为方面和结构方面。简单说,在行为方面就是要满足用户的功能性需求,而在结构方面就是要灵活、能够应对各种需求的变化,实施需求变更需要的精力只和变更的大小相关。(参见《整洁架构之道》读书笔记(一)

软件应该是“软”的。“软”意味着着能变化、能演化、能进化。

软件工程概念最初提出的时候常常与建筑工程进行类比。架构(Architecture)、蓝图(Blueprint)这些概念也都是从建筑工程借用来的。

但是人们渐渐发现软件工程和建筑工程是不一样的。建筑工程受到建筑材料的物理性质的约束,是硬的。为三层别墅画出蓝图、打下地基,以后再怎么样也没法“改”成摩天大楼。

但软件不一样。

iOS从2007年发布以来,每个版本都要添加上百项新功能。Face ID,Siri,AR这些新功能, 我相信都是最初的功能规划中没有的东西。连底层文件系统都从HFS+变成了APFS。

Emacs是上世纪70年代为纯字符终端开发的文本编辑器。今天它甚至可以运行在Android、iOS上,能够用来编写年龄比它小得多的语言的程序(不是简单的“编辑”源代码,而是有自动补全、实时编译、运行测试等IDE才有的功能)。

这就是软件的价值,或者说具有良好架构的软件的价值:能够适应运行环境的变化、应用场景的变化、不断提供新的功能。

软件工程最初提出的时候希望通过瀑布式的软件生命周期、通过大量的前期分析、评审等工作,尽可能准确、完整地捕捉用户需求,减少后期的需求变更对软件进度、成本的影响。但是到2001年,《敏捷宣言》提出要“拥抱变化”,因为人们意识到“变化”是必然的、“变化”有价值的。

  • 外部环境会变、业务模式会变,对实现业务模的软件系统的需求自然也会变;
  • 从没有信息系统到使用信息系统,用户对信息系统的理解会变。在没有信息系统时想定的功能,在实际使用了系统后发现不合适了、或者想出对信息系统的新用法了;
  • 技术的发展使得原来不可能实现或难于实现的功能有可能实现了。

软件最初版本上线的日子不是软件生命周期的结束,而是软件生命的真正开始。如果十月怀胎后降生的新生命一样,成长、变化才是生命的主旋律。不能变化的软件是没有生命力的软件。

但是对很多项目来说变更仍然是“万恶之源”。甲乙双方为每一个变更讨价还价;每一次上线都要提心吊胆、不知道会不会引入意想不到的错误;加班、延期总是家常便饭……

为什么会这样,因为本来应该“柔软”的软件却常常面领一个“刚硬”的约束——预算。

用户头一年申请项目立项和预算、来年招标寻找供应商,最后选择报价最低、或最接近预算的供应商,双方签订合同、开干。这依然是很多项目的常态。

在用户最初申请预算时只有一份非常粗略的项目功能范围,但它基本决定了整个项目的资金投入规模。而由于软件开发的特性,每个项目都有投入人力资源的合理规模,因此预算框定后也就基本框定了上线时间。但是一般项目的RFQ对于瀑布模型的软件工程项目来说,作为需求都是太粗略、太粗略了,还谈什么“敏捷”啊、“拥抱变化”啊,那不是找死吗?

在经济学中有一个不可能三角,即一个国家不可能同时拥有自由流动的资本、独立的货币政策、和稳定的汇率。在软件项目中存在类似的三角关系:即成本、范围和质量。

当成本、范围和质量形成平衡关系后,我们不可能只改变其中的一项,而保持另两项不变。或者说,当给定其中任意两项后,另外第三项也就基本确定了。

具体到需求变更的场合,也就是软件的功能范围发生变化的时候,成本和质量之间至少要有一项发生变化。如果要求成本不变,那么就只能牺牲质量。当然,软件行为方面的质量,也就是满足功能需求方面的质量是不能被牺牲的,因为这是很容易被测量的,看看缺陷率就好了嘛!那么被牺牲的就只能是软件结构方面的质量,也就是降低软件适应未来变化的能力。

但是软件结构方面的质量也是不可能无限制被牺牲掉的。毕竟结构再差的程序写出来也是需要时间的,而且结构越差的程序缺陷也可能越多、修复缺陷也会越复杂;另外在今天牺牲了软件结构方面的质量去应对功能范围的扩大,使得软件越来越难以修改,也就意味着在未来新的修改需求对成本的压力也会越来越大。

所以任何在开始就固定了项目预算和时间节点的项目,到最后总会走到突破预算和时间节点来应对范围变化的那一天。当然,用户支付的开发费用可能会保持不变,那么增加的成本就会以别的形式表现出来,包括但不限于:

  • 开发公司利润减少、直至亏损;
  • 程序员掉的头发;
  • 程序员的女朋友;
  • 接手维护项目的程序员掉的头发和他的女朋友;

因此要想软件“软”起来、灵活起来,项目预算也要软起来、灵活起来。

首先要认识到软件投入不是单纯的成本开始。至少对以盈利为目的的组织来说,软件最核心的两个价值,一个是赚钱、一个是省钱。因此不仅要算投入、还要算产出。与其想着在软件开发上降成本,不如想着怎么让软件系统增效益。

其次要充分认识软件在结构方面的价值。在同样完成当前功能需求的前提下,一个灵活的、易于修改和变化的软件系统,其价值要远远超过僵硬的、难以修改的软件系统。一个足够“软”的软件才是对投资的最好保护,才是最省钱的软件。

最后,只有用户和软件开发者之间形成稳定的长期合作关系,软件开发者才会以长期发展的眼光来看待软件架构的质量,而不会轻易地牺牲结构方面的质量去应对功能需求方面的成本和时间进度压力。



blog comments powered by Disqus