流程式编程

简介:

流程式编程在许多商业框架中都有实现。

Tiny框架构建者认为,流程式编程与普通的编程式开发,各有其应用场景及优势。

编程式开发,程序员有更大的自由度,当然也正是由于其具有的极大自由度导致项目的进度、质量方面带来了极大的不确定性,同时对于未来的维护方面也可能挖下了巨大的坑。

而流程式编程呢,对于开发人员有了较大的限制,也就是说,只能用已经开发好的组件进行开发,或者扩展自己的组件进行开发。开发过程当然就受限制了,可能在项目初期,会带来一定的开发效率降低,但是最后的维护成本方面会有比较大的节省,当然,其最大的被诟病的就是在实现某些功能的时候,不方便;还有就是程序员认为长时间使用流程编排式开发会降低开发能力,而受到抵制。

正是由于编排式编程在后期维护方面带来的便利,使得流程编排式开发方式存在其实际的生存空间。当然,Tiny框架提供的流程编排式框架,提供了与一般常见流程编排开发方式不一样的特性。

充分支持面向对象特性的流程编排开始模型

首先来从一个简单的示例看起:

?
1
2
3
4
5
6
7
8
9
10
11
12
< flow id = "1000" name = "Hello" >
     < nodes >
         < node id = "begin" >
             < component name = "helloWorldComponent" >
                 < properties >
                      < property name = "name" value = "World" />
                      < property name = "resultKey" value = "" helloInfo"" />
                 </ properties >
             </ component >
         </ node >
     </ nodes >
</ flow >

组件helloWorldComponent的源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class HelloWorldComponent implements ComponentInterface {
     String name;
     String resultKey;
 
     public String getResultKey() {
         return resultKey;
     }
 
     public void setResultKey(String resultKey) {
         this .resultKey = resultKey;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this .name = name;
     }
 
     public void execute(Context context) {
         context.put(resultKey, String.format( "Hello, %s" , name));
     }
 
}

从上面的代码可以看出,其实它的逻辑非常简单。提供了两个自定义属性,一个是name,一个是resultKey,最后在其execute方法中,从其实现逻辑可以看出,它就是把“Hello, ”加上输入的名字,放在了环境变量的resultKey当中,然后返回。

流程组件的接口,也非常简单,如下:

?
1
2
3
4
5
6
7
8
public interface ComponentInterface {
     /**
      * 组件执行方法
      * @param context 组件执行的环境
      */
     void execute(Context context);
 
}
所以,其实现也是非常简单的。

下面是调用此流程的方法:
a.按默认开始结点开始执行

?
1
2
3
Context context = new ContextImpl();
flowExecutor.execute( "1000" ,  context);
assertEquals( "Hello, luoguo" , context.get( "helloInfo" ));
b.从指定节点开始执行 
?
1
2
3
Context context = new ContextImpl();
flowExecutor.execute( "1000" , "begin" , context);
assertEquals( "Hello, luoguo" , context.get( "helloInfo" ));
可以看到确实是执行并返回了结果,但是它的执行机理是怎么样的呢?? 
看一个更全面的流程配置: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
< flow id = "1000" version = "1.0" privateContext = "false" extend-flow-id = "" name = "Hello" title = "你好示例" default-node-id = "end" begin-node-id = "begin" end-node-id = "end" enable = "true" >
   < description >some thing....</ description >
   < nodes >
     < node id = "begin" >
       < component name = "helloWorldComponent" >
         < properties >
           < property name = "name" value = "&quot;luoguo&quot;" />
           < property name = "resultKey" value = "&quot;helloInfo&quot;" />
         </ properties >
       </ component >
       < next-nodes >
         < next-node component-result = "OK" exception-type = "java.lang.Exception" next-node-id = "end" />
       </ next-nodes >
     </ node >
   </ nodes >
</ flow >
其中flow节点的属性含义为: 
id,唯一确定一个流程 
privateContext,如果是true,则在流程单独申请一个context,否则共用调用者的context,这样可以有效避免环境变量冲突问题 
extend-flow-id,继承的流程id,这个继承id是一个非常强大的功能,后面详细介绍 
version版本号,同一id的流程可以存在多个版本,访问时,如果不指定版本则默认采用最新版本 
name,title仅用于说明其英文,中文名称,易于理解而已。 
default-node-id表示,默认执行节点,即如果一个组件执行完毕,其项值没有指定下一处理节点则执行默认节点 
begin-node-id,开始节点 
end-node-id,结束节点 
如果不指定,则begin-node-id默认为begin,end-node-id默认为end 
node节点:id必须指定,在一个流程当中id必须唯一。 
component节点 
class-name用于指定组织实现类名 
properties是组件的属性列表 
property中的name与value是组件的属性的值,value,这里传入的是个字符串,但是实际当中可以处理中可以非常灵活,后面再介绍。 
next-nodes,是指根据执行结果进行后续处理的规则。 
next-node,具体的一条规则,component-result,匹配项,支持正则表达式,节点中的组件执行结果进行匹配,匹配成功则执行此规则中的下一节点。 
exception-type是异常的类名称,如果出现异常且与这里定义的类型匹配,则执行此规则中的下一节点。 
关于继承

上次说到继承,流程继承实现起来是非常简单的,只要在extend-flow-id属性中指定即可。
继承不支持多继承,即流程只能继承自一个流程,但是可以支持多层继承,即
a>b>c>d.....
实际开发过程中,不要把继承搞得太复杂,这样会把程序逻辑搞得更难理解的。
继承实际会起到什么作用呢?
首先,会继承一些属性,另外会把节点信息继承过来。
简单来说就是:两者都有,当前流程说了算,当前没有,父流程说了算。
继承应用到什么场景呢??
继承应用于业务处理的模式非常相似,只有中间处理环境不同的时候。
比如:
A  B  C  D ---O--- -D -C -B -A
类型的业务处理流程,只有O不同,其他处理模式完全相同,此时采用继承方式都非常舒服了,
只要定义父流程,在子流程中只用定义O一个流程节点即可。以后要统一进行流程调整,只要在父流程中进行调整就可以了。
比如:flow aa定义为:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
< flow id = "aa" name = "aa" >
   < nodes >
     < node id = "begin" >
       < next-nodes >
         < next-node component-result = "begin" next-node-id = "hello" />
       </ next-nodes >
     </ node >
     < node id = "hello" >
       < component name = "helloWorldComponent" >
         < properties >
           < property name = "name" value = "" luoguo""/>
           < property name = "resultKey" value = "" helloInfo""/>
         </ properties >
       </ component >
       < next-nodes >
         < next-node component-result = "OK" next-node-id = "end" />
       </ next-nodes >
     </ node >
   </ nodes >
</ flow >
flow bb定义为:

?
1
2
3
4
5
6
7
8
9
10
11
12
< flow id = "bb" name = "bb" extend-flow-id = "aa" >
     < nodes >
         < node id = "hello" >
             < component name = "helloWorldComponent" >
                 < properties >
                     < property name = "name" value = "LG" />
                     < property name = "resultKey" value = "" helloInfo"" />
                 </ properties >
             </ component >
         </ node >
     </ nodes >
</ flow >
则流程bb也可以顺利执行,且执行结果是Hello, LG

流程的可重入性:

一般的流程编排引擎中,流程是不可重入的,也就是一个流程一定是从开始节点起执行,一定执行到结束结点结束。在Tiny流程引擎中,不仅可以在当前流程中进行切换与转接,还可以流转到其他流程的节点当中,这在业务处理及页面处理,流程处理方面都提供了极大的使得,但是这也是一个双刃剑,在提供了这么灵活的功能的同时,也会导致业务流程看起来比较复杂,因此,控制方面最好由架构师或核心开发人员来编写,普通开发人员只开发具体的业务点即可。
小结

Tiny框架提供的流程编排引擎,功能强大,扩展灵活,支持了部分面向对象的特性,比如继承、比如重载,再加上流程的可重入性,使得它更加灵活,便捷。当然,流程编排式编程还有一个非常强大的功能,就是可以进行在线式编程,Xml式流程配置完毕,马上就可以执行出结果。

相关文章
|
6月前
|
数据可视化 数据库连接 测试技术
【软件设计师备考 专题 】编写外部设计文档:系统流程图和功能说明书
【软件设计师备考 专题 】编写外部设计文档:系统流程图和功能说明书
191 0
|
1月前
|
存储 设计模式 Java
为什么我们在程序开发设计中要基于接口而非实现编程?
为什么我们在程序开发设计中要基于接口而非实现编程?
60 1
|
2月前
|
监控 数据挖掘 BI
项目管理流程全解析及关键步骤介绍
项目管理流程是项目成功的基石,涵盖启动、规划、执行、监控和收尾等阶段。Zoho Projects 等软件可提高效率,支持结构化启动与规划、高效执行与协作及实时监控。这些流程和工具对项目的全局视角、团队协作和风险控制至关重要。项目管理软件适用于不同规模企业,实施时间因软件复杂度和企业准备而异。
86 2
|
6月前
|
搜索推荐 JavaScript Java
项目开发过程中实际遇到的几个问题处理
项目开发过程中实际遇到的几个问题处理
167 2
|
6月前
|
敏捷开发 测试技术 持续交付
面试题1: 测试常见工作流程
面试题1: 测试常见工作流程
114 0
|
6月前
|
SQL 前端开发 Java
Java后端接口编写流程
Java后端接口编写流程
120 0
|
测试技术
测试思想-测试流程 需求开发与管理简述
测试思想-测试流程 需求开发与管理简述
94 0
测试思想-测试流程 需求开发与管理简述
|
XML SQL JavaScript
当前在工作中使用到的高效的代码编写方法
当前在工作中使用到的高效的代码编写方法,让代码去生成重复性质的代码
130 0
|
分布式计算 大数据 Spark
阶段练习_代码编写 | 学习笔记
快速学习 阶段练习_代码编写
阶段练习_代码编写 | 学习笔记
|
SQL 敏捷开发 前端开发
接口自动化测试实践指导(上):接口自动化需要做哪些准备工作
接口自动化测试实践指导(上):接口自动化需要做哪些准备工作
接口自动化测试实践指导(上):接口自动化需要做哪些准备工作
下一篇
无影云桌面