功件与面向功件编程

自从计算机出现以来,计算机硬件和软件的发展轨迹完全不同,计算机硬件的发展可以用波澜壮阔来形容,从电子管、晶体管发展到集成电路、大规模集成电路,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项目或者这个软件产品包含“安装、首页、用户、授权、提示页”这几个主要功能。其内部具体实现细节不再赘述,请访问Functree

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

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

上述功件与面向功件编程的论述内容和示例项目,均位于https://www.functree.cn/,请大家批评指正。

时间: 2024-08-06 00:29:02

功件与面向功件编程的相关文章

第14章1节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程

到此为止我们描述的MonkeyRunner对应用的点击拖放等操作都是直接通过指定坐标点来实现的,比如下面触摸一个坐标点为(60,90)的按钮的脚本例子: 1 device.touch(60,900,MonkeyDevice.DOWN_AND_UP) 代码14-1-1 直接使用坐标点操作应用 这样子做的话代码会存在以下几大缺点: 缺乏易用性:要操作某个控件之前需要先想办法如通过工具来定位该控件的坐标点 可扩展性差:当屏幕分辨率改变的时候需要另外写一个通用算法来处理坐标点的变化 可读性差:代码到处都

即时通讯软件开发 几种网络编程方式

即时通讯软件开发 几种网络编程方式: ISAPI.CGI.WinInet.Winsock 它们之间的区别: 1)ISAPI主要是开发基于浏览器客户端与服务器端程序.效率比CGI方式高,而且也扩展了CGI没有的一些功能.(基于TCP/IP模型中的应用层) 2) CGI主要是开发基于浏览器客户端与服务器端程序.(基于TCP/IP模型中的应用层) 3) WinInet主要是开发客户端程序.(基于TCP/IP模型中的应用层) 4) Winsock主要是基于socket来开发客户端与服务器端程序.(基于T

【读书笔记-《Android游戏编程之从零开始》】8.Android 游戏开发常用的系统控件(系统控件常见问题)

Android 中常用的计量单位Android有时候需要一些计量单位,比如在布局Layout文件中可能需要指定具体单位等.常用的计量单位有:px.dip(dp).sp,以及一些不常用的pt.in.mm.下面详细介绍下这些计量单位之间的区别和联系.in:英寸(长度单位):mm:毫米(长度单位):pt:磅/点,1/72英寸(一个标准的长度单位):sp:全名 scaled pixels-best for text size,放大像素,与刻度无关,可以根据用户的字体大小就行缩放,主要用来处理字体的大小:

(转载)VS2010/MFC编程入门之二十二(常用控件:按钮控件Button、Radio Button和Check Box)

因为私人问题,鸡啄米暂停更新了几天,首先向关注鸡啄米动态的朋友说一声抱歉. 言归正传,鸡啄米上一节中讲了编辑框的用法,本节继续讲解常用控件--按钮控件的使用. 按钮控件简介 按钮控件包括命令按钮(Button).单选按钮(Radio Button)和复选框(Check Box)等.命令按钮就是我们前面多次提到的狭义的按钮控件,用来响应用户的鼠标单击操作,进行相应的处理,它可以显示文本也可以嵌入位图.单选按钮使用时,一般是多个组成一组,组中每个单选按钮的选中状态具有互斥关系,即同组的单选按钮只能有

Swift中面向协议的编程

什么是面向协议的编程? 面向协议的编程,是一种编程范式. 编程范式,是一个计算机科学用语.维基百科中的解释是,计算机编程的基本风格或典型模式.通俗来说,就是解决某一个问题的方法不同方法和思路. 像大家很熟悉的,面向对象编程以及面向过程编程,都是一种编程范式. 面向过程编程,关心的焦点是解决某一个问题需要多少步.而面向对象的编程关心的是解决问题需要多少个对象,以及这些对象之间的组织联系. 解释完了编程范式这个名字含义之后,我们继续回到正题上来. 既然面向协议编程,与面向对象,面向过程一样,是一种编

面向对象的编程和面向过程的编程有什么区别

C语言是面向过程的编程,它的最重要特点是函数,通过主函数来调用一个个子函数.程序运行的顺序都是程序员决定好了的.它是我学的第一种程序语言. C++是面向对象的编程,类是它的主要特点,程序执行过程中,先由主函数进入,定义一些类,根据需要,执行类的成员函数,过程的概念被淡化了(实际上过程还是有的,就是主函数的那些语句),类就是对象,所以我们称之为面向对象程序设计. 不同点:1.编程模型 所有计算机均由两种元素组成:代码和数据.精确的说,有些程序是围绕着"什么正在发生"而编写,有些则是围绕&

Delphi 编写ActiveX控件(OCX控件)的知识和样例(有详细步骤)

一.ActiveX应用情况简介: ActiveX控件也就是一般所说的OCX控件,它是 ActiveX技术的一部分.ActiveX是微软公司推出的基于组件对象模型COM的技术,包括对Windows 32位应用编程接口(Win32 API)和组件对象模型的一系列扩充和增强,目标是把计算机桌面环境与因特网环境集成起来,同时保护在Windows技术中现有的开发投资.微软的 ActiveX技术根本上就是修改过的OCX技术,使它能够跨越Internet,主要是使用WWW来传递控件.            A

winform-事件之公共控件

事件参数: object sender - 事件主体 EventArgs e - 事件数据 函数体 - 我进行的操作 制作思路: 做一个按钮,就只想这一个按钮的功能就行了 如果需要其它按钮来进行辅助,这个情况 只会出现在,你这个按钮做不下去了,才需要去考虑是否有其它按钮可以来帮忙的 ------------------------------------------------------------------------------------------------------------

java实现文件夹(包括其中的子文件夹、子文件)的复制——递归

这是学校java课的一道实验题,题目如下:编程,根据指定的源和目标位置,完成指定文件或文件夹(包括其中的子文件夹.子文件)的复制. 以下是我的实现,使用了递归: 1 package com.simon.myfinal; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.InputStream; 7 8 /** 9 * Crea