早在2018年时,脑海中就有了面向流程编程的概念,并且要开发一款面向流程编程的框架,可惜,由于工作繁忙,这事一直被搁浅;现在终于动工啦;本文先简单讲几个大家都熟悉的编程范式,然后再引入 面向流程编程范式;
1. 编程范式
编程范式,范:模范、典范之意;式:模式、方法;范式 即 典范的模式 之意;编程范式 是一类典型的编程模式;
常听到的编程范式有:面向过程编程、面向对象编程、响应式编程 等等
1.1. 面向过程编程
面向过程编程,也被称为命令式编程,应该是最原始的一种编程范式;代表语言有:汇编语言 等;
面向过程的编程思想是:站在计算机的角度,去设计一个顺序执行的指令序列,这个指令序列告诉详细地描述的计算每一步操作 用以实现我们想要的功能;如,实现两个数相加:
-
将 数A 读到 计存器A
-
将 数B 读到 计存器B
-
将 计存器A 的值 和 计存器B 的值 相加,并将结果存储在 计存器A
-
返回 计存器A 的值;
面向过程编程 是以逻辑为中心,数据只是作为执行逻辑的附属信息,这种方式适合以性能为主要指标的 算法类程序设计;
1.2. 面向对象编程
面向对象编程的思想是:将复杂的事物抽离成一个个独立的对象,每个对象都有自己的行为,逻辑的执行 变成 对相关对象 发送 消息,让相关对象自己去执行他擅长的行为(功能、逻辑);
如:播放电影
-
向电视 发送 消息,告诉它
播放 《星际穿越》
;
-
电视查找《星际穿越》视频资源;
-
电视读取《星际穿越》的视频 和 音频;
-
电视 向 显示器 发送 消息,告诉它
显示指定的视频信号
;
-
电视 向 音响 发送 消息,告诉它
播放指定的音频信号
;
用面向过程的编程范式来描述的话,如下:
-
查找《星际穿越》视资源;
-
读取《星际穿越》的视频;
-
将 视频数据的帧中的每一像素 按照指定的速度 和 周期 分别呈现在显示器上;
-
将 音频数据 转为模拟信号;
-
将 模拟信号 施加到扬声器的磁感线圈上;
面向对象编程 是以数据为中心,将一特定数据的集合抽象为特定类型的对象,这些数据的处理逻辑以对象的行为的方式附加到对象上,对象之前的协作通过以
发消息
的方式来通信,这种方式使得程序设计更加模块化,也更适合对事物建模,适合用来进行复杂的程序设计;
1.3. 响应式编程
响应式编程的思想是:监听 数据流 或 变化,当有 新的数据流 或 变化 时,执行相应的操作,操作的结果 也是可被监听的 数据流 或 变化;
例如:
-
在非响应式编程范式中,
a=b+c
表示将
b
和
c
相加的结果 赋值给
a
,而之后改变
b
或
c
的值不会影响
a
。但在响应式编程范式中,
a
的值会随着
b
或
c
的更新而更新。
-
电子表格程序就是响应式编程的一个例子。单元格可以包含字面值或类似
=B1+C1
的公式,而包含公式的单元格的值会依据其他单元格的值的变化而变化。
响应式编程最初是为了简化交互式用户界面的创建和实时系统动画的绘制而提出来的一种方法,但它本质上是一种通用的编程范式。
应用响应式编程范式的库有:
ReactiveX
系列的库(如:RxJS、RxSwift、RxJava 等等)、组件化框架(如:Vue、React)中的数据的单向 或 双向 绑定 等,Vuex、Redux 等等;
2. 面向流程编程
2.1. 定义
把复杂的程序逻辑抽象成流程,将流程中的每一步抽象成一个节点,节点与节点之间通过 管道(也可称之为边) 连接起来,管道负责节点之间的数据传递和处理,像这样将 程序逻辑以流程化的方式实现的编程方式 叫
面向流程编程范式
。
2.2. 产生背景
在做程序开发时,经常有以下痛点
-
文档、设计图缺乏:项目开发期间,忙着赶进度,所以基本上不会有文档,而事实上,即使开发完成后,绝大多数项目也没有文档;没有文档将会持续增加日后的人员变更、项目维护的成本;
-
程序逻辑不易梳理:很多中小型企业,项目初期追求低成本、进度快,则代码质量十分低下,耦合度极高,时间一长,原开发人员可能还需要仔细看代码才能理清逻辑,更别说新人了;
-
不易扩展、不易定制化:在项目的迭代过程中,经常会有对已有的逻辑中的部分环节做改造、定制,或是 增加 新的环节,尤其那些面向企业的项目,比如:原来页面顺序是
a->b->c
,现在要求从
d
页面也能跳到
b
页面(如下图);通常开发人员会找到 d 和 b 两个页面,可能由于代码写的耦合性过高,导致要查阅更多页面的逻辑,然后在相关页面里添加定制化逻辑;
2.3. 解决方案
程序逻辑可以用流程的方式来描述,如下图:
即使对 GUI(图形用户界面)程序的用户界面的交互逻辑而言,也是如此;下图描述了应用程序用户界面的构成 (
详情请看
应用软件界面结构和源码目录结构
):
所以程序逻辑是可流程化的,既然这样,那我们可以尝试通过下面这种方式来实现程序的逻辑:
-
把程序流程中的每个逻辑单元抽象成节点;
-
然后通过 管道(即边) 对节点进行连接;管道可以用来在两个节点之间转换数据;
-
当激活某个节点后,节点封装的逻辑单元会执行,并决定是否激活下一个节点;
-
当需要激活下一个节点时,可以给下一个节点传递数据,数据 会通过 管道 传递到下一个节点,管道 可转换数据使其符合下一个节点要求;
像这种编程的方式就称为
面向流程编程
;
为了更可读、更易用,还可以通过 配置 或者 一种比较形像化的语言来(如:Dot语言) 描述 节点 与 管道 或 节点 之间的关系,这样也实现了 节点 与 流程关系的解耦;
并且还可以基于 配置 或 形象化语言 开发 流程可视化的 展示、调试、编辑 等相工具;
这样的话,人们仅仅通过程序流程的 配置 或 形像化语言 或 生成的可视化图形 就能很清晰地了解程序的流程结构,并且日后的改动也极其方便;
3. 面向流程编程范式和流程工具的区别
现在已经有很多流程图相关的工具了,如:Visio、OmniGraffle 等等,虽然它们是用来制作流程图的,但这些软件本身的程序设计 并不一定是用 面向流程的编程范式 来设计的;
面向流程编程范式 强掉的是 将程序的逻辑步骤抽象成 节点,然后 用流程化的方式将节点 关联起来 的这种编程方式;而流程工具是为实现 流程相关的 业务需求 而开发的工具;
在流程工具中,流程是指 业务需求,是程序要实现的效果的目标,而在 面向流程编程范式中,流程是指开发程序的方式,并非程序实现的效果的目标;