自从计算机出现以来,计算机硬件和软件的发展轨迹完全不同,计算机硬件的发展可以用波澜壮阔来形容,从电子管、晶体管发展到集成电路、大规模集成电路,CPU从单核发展到多核,显示器从电子屏发展到液晶屏,硬件技术和产品不断更新换代,硬件生产力不断出现飞跃式发展;而计算机软件却一直以一种缓慢的速度发展,虽然编程语言从二机制、汇编语言发展到了高级语言,各种软件技术和框架不断涌现,但软件产品生产力的提升非常缓慢。回头看近二十年计算机硬件生产力和软件生产力的发展速度,我们会发现,软件生产力的发展速度,远远低于硬件生产力的发展速度。

      分析这种巨大反差的根本原因,可以发现,计算机硬件的发展是站着工业化生产这个巨人的肩膀上的,而计算机软件仍然处于低水平的手工业生产阶段。不是吗?一个软件产品需求出来,需要建立一个团队负责软件需求、设计、开发、测试、安装部署等软件产品生产周期的各个阶段,需要程序员一行行手工编写代码去实现软件产品功能,下一个软件产品的开发,重复上述过程,无一例外,社会化的分工与协作、标准化、模块化、快速迭代与大规模生产等工业化概念,在软件产品的生产过程中很难见到,现在的开发团队、组织、公司,恰如古代的手工作坊。所以,目前的软件开发还处于手工业生产阶段。

      软件的未来和发展趋势就在于软件生产的工业化。有人说软件太复杂了,各种依赖包、版本控制、协议和编程语言不同等一系列问题,导致想要实现类似硬件的工业化生产几乎不可能。但是,这种软件的复杂性又来自哪里呢?对于全世界的软件开发人员来说,从来没有一个统一的规范来约束其开发过程,文件名称、方法名称、参数变量等等随便定义,数据存储与返回值没有约束,这样开发出来的软件很难重用和互联互通。各种编程语言有各自的编码规范,而这些编码规范在哪个软件产品中起作用,要看开发团队或开发人员的自觉。所以,软件的复杂性在于没有一个工业化规范来约束软件产品的开发和生产。

      那么,软件工业化实现起来真的很难吗?我们摒弃软件复杂性的说法,看看如何用功件和面向功件编程,实现软件工业化生产。

      在阐述功件之前,我们先澄清一下功件和目前软件开发中的组件(构件)的区别。

      首先看一个软件产品中的组件,如下图:

      从上图可以看到,虽然“软件1”中组件可以实现软件产品中的部分功能,但上图中的灰色区域,却需要软件开发人员一行行编写代码、文件配置等操作作为粘合剂,将这些组件粘合在一起才能生产出一个软件产品。开发下一个产品“软件2”呢,和“软件1”的开发没有区别,如下图:

      假如开发一个“软件3”,其包含了“软件1”和“软件2”中的部分组件,会是什么情况?看下图:

      从上图可以看出,即使前两个产品中的部分组件可以直接应用到“软件3”中,但是灰色区域部分的工作是必不可少的。

      下面,我们看看“软件1”的理想构成是什么样子的,看下图:

      从上图可以看到,“软件1”由3个功件构成,没有灰色区域;假如开发另外一个产品“软件2”:

      从上图可以看出,“软件2”中的功件X不需要重新开发,这会节省很大一部分工作量。同样,假如开发产品“软件3”,包含了“软件1”和“软件2”中的部分功件,会是什么情况?看下图:

      从上图可以看到,只要将“软件1”和“软件2”中的功件进行组合,就可以组成“软件3”,没有灰色区域,即可以在不需要开发人员一行行编写代码、文件配置的情况下,完成了“软件3”的生产。假如,“软件1”和“软件2”由不同的团队来实现,就更加能够体现出功件技术相对于传统组件(构件)技术的优势。

      下面看看什么是功件和面向功件编程:功件,简称Func,全称为软件功能件,即软件功能模块;面向功件编程,简称FOP,即Func Oriented Programming,其以“功件规范”为规约进行软件产品的开发。在这里,抛开技术实现细节,从业务整体角度来看待一个软件产品,这个软件产品包含哪些功能模块,这些功能模块就可以定义为功件,也就是说,仅这些功能模块组合一起,就能生成这个软件产品。

      下面以Jamobo2项目为例来说明如何用功件技术开发一个软件产品:

      从上图可以看到,Jamobo2软件项目的整个文件结构,根据“功件规范”要求,所有功件均位于f目录下,而每个功件在一个软件项目中,仅有一个,功件由一个功件主文件和一个功件主目录组成。上述Jamobo2项目中有以下几个功件,其中底层功件有:Authorization(授权)、Setup(安装)、User(用户)、X(公共类),显示层功件有:AlertPage(提示页)、SetupPage(安装页)、UserPage(用户页)、XPage(首页)。由这些功件组成,可以看到Jamobo2这个Web项目或者这个软件产品包含“安装、首页、用户、授权、提示页”这几个主要功能。其内部具体实现细节不再赘述,请访问。

      根据上述内容,可以总结以下几个面向功件编程的优点:

      1. 开发周期短,因为不需要编写一行行代码作为粘合剂,也不需要很多的配置文件。
      2. 功件位于一个目录(空间)下,这样能够让开发者很快把握软件项目的功能模块组成,降低软件产品升级、维护的复杂度。
      3. 当开发一个新项目的时候,完全可以直接把其他项目的功件直接搬过来使用,可能仅仅需要进行一些小小的改造或不需要任何改造,即可应用到新项目中。
      4. 这样简单的、规范的功件树结构,会使得自动化开发、测试、部署、运维的难度大大降低,从而可以更容易的开发出一些自动化工具来辅助整个软件产品生命周期的各个阶段,进一步提高开发效率和缩短工期。
      5. 功件的开发,将开发人员从横向(地域)、纵向(时间)两个方面解放出来,从而使得不同地域、不同时间点、擅长不同专业领域的人员能够配合起来,实现社会化的分工与协作。

      在面向功件编程过程中,需要注意以下几个问题:

      1. 按照“功件规范”开发功件,会导致开发人员的开发自由度降低,这是标准化、工业化、模块化生产软件产品的必要条件。
      2. 某些软件框架不能用了,或者需要进行改造才能符合“功件规范”要求,不可避免出现重新造轮子的疑问和争论。
      3. 在一个软件项目中,功件之间应尽量减少继承关系,功件尽量做到功能和数据的自包含,减少对其他功件的依赖,这样可能导致软件产品的尺寸增大。