业务流程引擎

一般的时候,我们都采用编程式开发,编程式开发的好处非常明显:直接、高效、自由,当然其缺点也是有的,与其优点刚好相对,因为直接,所以有些变化都要进行代码上的修改;因为高效,所以一旦出问题,导致的结果也比较严重,因为自由,所以带来的修改风险也比较大。

这也就是许多大的公司都在进行流程化开发的重要原因之一,比如:上海普元,Livebos, Justep,还有许许多多知名不知名的公司都有类似的流程化开发引擎存在,通过流程化开发,增强代码的复用性,降低软件开发成本及测试成本,提升软件的可维护性及降低维护成本。

Tiny框架在这方面也有自己的方案,Tiny主要考虑几个方面的问题:

a.组件扩充的便捷性

组件的扩充的便捷性是指,流程其实玩的就是组件,如果组件扩充起来非常困难,会直接影响到流程引擎的可用性。所以Tiny框架的流程引擎的组件结构非常之简单,仅有一个接口方法;流程组件的注册与加载也是非常重要的,如果在扩充流程组件的时候,需要复杂的注册或配置过程,这个时候流程扩充的便捷性也会大大降低。Tiny框架采用了引用即注册的方案,只要把流程组件放入系统运行环境之间,就完成了流程组件的注册,即可以在流程中使用,便得流程组件的扩充的便捷性大大提高。

b.流程的面向对象特性支持

流程的面向特性支持是指在Tiny框架中流程是具有面向对象的特性的。流程可以进行继承,这样带来一个好处就是多个流程中重复的部分,可以定义在一个父流程中,然后子流程只要继承父流程,即可;流程节点是可以被覆盖的,也就是说,在父流程中可以定义一个空节点,但是流程中定义了流转关系,但是流程节点的实现留在子流程中实现;

c.流程的易编辑性

流程的编辑必须方便、容易,有专门的流程编辑工具更好,没有的时候,使用普通的Xml编辑器也可以方便的进行编辑。

d.流程的可重入性

一般的流程引擎都是不可重入的,也就是只能从开始执行,执行到结束结点之后完成。Tiny流程引擎支持流程重入,也就是说,不一定是从开始结点执行,可以从任意一个结点执行。这个机制为程序的逻辑提供了非常大的自由度,可以利用此特性容易的构建页面流引擎或工作流引擎。即使是业务流程引擎,也会由此获得更大的自由度。

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

呵呵,说了这么多,大家理解起来可能还是比较抽象,那就来个例子看看:

?


1

2

3

4

5

6

7

8

9

10

11

<flow id="1000" name="Hello">

    <nodes>

          <node id="begin">

                <component class-name="org.tinygroup.flow.HelloWorldComponent">

                    <properties>

                        <property name="name" value="world" />

                    </properties>

                </component>

          </node>

    </nodes>

</flow>

HelloWorldComponent的源码如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

public class HelloWorldComponent implements ComponentInterface {

    String name;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public void execute(Context context) {

        context.put("result", String.format("Hello, %s", name));

    }

}

可以看出,所有组件必须实现ComponentInterface 接口

从其实现逻辑可以看出,它就是把“Hello, ”加上输入的名字,放在了环境变量的result当中。

下面看看执行结果:

a.按默认开始结点开始执行

?


1

2

3

Context context = new ContextImpl();

flowExecutor.execute("1000",  context);

assertEquals("Hello, world", context.get("result"));

b.从指定节点开始执行

?


1

2

3

Context context = new ContextImpl();

flowExecutor.execute("1000","begin", context);

assertEquals("Hello, world", context.get("result"));

可以看到确实是执行并返回了结果,但是它的执行机理是怎么样的呢??

实际上,上面的流程是一个简化的流程,就是说Tiny流程引擎的有些参数不输入,也可以按照约定正确的执行,实际上写得完整的话,例子是下面这个样子的:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

<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 class-name="org.tinygroup.flow.HelloWorldComponent">

        <properties>

          <property name="name" value="world"/> <span></span> </properties>

      </component>

      <next-nodes>

        <next-node 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

<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 class-name="org.tinygroup.flow.HelloWorldComponent">

        <properties>

          <property name="name" value="world"/>

        </properties>

      </component>

      <next-nodes>

        <next-node next-node-id="end"/>

      </next-nodes>

    </node>

  </nodes>

</flow>

flow bb定义为

?


1

2

3

4

5

6

7

8

9

10

11

<flow id="bb" name="bb" extend-flow-id="aa">

<nodes>

<node id="hello">

<component class-name="org.tinygroup.flow.HelloWorldComponent">

<properties>

<property name="name" value="world" />

</properties>

</component>

</node>

</nodes>

</flow>

则流程bb也可以顺利执行,且执行结果是Hello, world 

非常重要的一个亮点就是属性赋值。 
属性赋值是否好用,决定了框架的易用性。 

可以支持常量赋值"1"表示数字常量 
aa 表示字符串常量可以支持,环境变量赋值 
比如:xx表示从环境变量取xx键值的对象 
可以支持属性赋值 
比如:xx.abc表示取环境变量xx的属性abc 
比如:xx.abc.def表示取环境变量xx的属性abc的属性def 
可以支持组合赋值 

比如:${in:aa.abc.def}-${in:bb.cc.dd}   
表示把环境aa中的属性abc的属性def中间加"-"再加上环境变量bb中的cc的属性的dd属性 
其中属性的层次不受限制。 

另外,取值方式,也支持自行扩展: 
比如:可以用${in:xmlkey.aa}也取在环境中xmlkey对应的xml节点的aa属性 
所以,只有想不到的,没有做不到的。  

应用开发与部署方式,比较典型的有B/S与B/A/S,C/A/S等。对于B/A/S和C/A/S方式,因为A与B和C是分离部署的,所以,所有的内容都需要是通过Context进行传递的。 

如果是通过分离式部署,那么就需要通过网络来传递请求环境数据。 

如果是想通过B/S环境来构建系统,此时就会期望通过HTTP处理线程来同布调用流程处理结果。 
同时,有时流程处理的数据可能是在Request,RequestAttribute,Session,Cookie中,如果把这些数据COPY到环境当中去,其实是有较大的性能消耗的。 

本流程引擎即支持通过服务方式调用,也可以通过短路方式进行调用。 
虽然我们推荐使用B/A/S体系架构,但是不能否认,目前我们的许多产品还是在B/S架构下运行的。 

但是好在,这个对于流程引擎来说,他并不直接访问Request和Session,Cookie等内容,所以,即使是集成在一起部署,也不妨碍进行分离式部署,依然可以保证服务的无状态特性,前提就是需要实现一个Context的接口。 

小结:

Tiny的流程引擎,提供了相当强悍的功能及扩展性,上面只说了一部分,有些也没有完全说清楚,实际上,还提供了包含EL表达式等许多高级功能,对于期望进行流程式编排开发来说,有相当好的支持。

目前在Tiny框架中,业务流程编排及页面流程编排都是基于此引擎构建,应用效果非常良好。未来会基于其构建工作流引擎。

时间: 2024-09-06 23:55:55

业务流程引擎的相关文章

在SOA中实现业务规则和业务流程

使用面向服务的体系结架构(SOA)的其中一大动力在于提升企业的敏捷度,并将不可避免的改变所带来的影响减到最小.这一般通过把经常改变和相当稳定的实现工件进行分离来完成.支持这种分离的常用方法是分解(decomposition)和封装(encapsulation).SOA的分解导致服务的定义代表更稳定的工件,而业务流程则代表更经常变化的工件1.在一个典型的SOA实现中,服务不会经常改变,但是非常经常地被组合和重组来构建/修改企业的解决方案. 这种分解不会直接标明业务规则的位置--整体IT实现中另一个

基于业务流程的制造云服务组合模型

基于业务流程的制造云服务组合模型 赵秋云 魏乐 舒红平 为了提高云制造系统中制造云服务的组合成功率,实现组合云服务与用户业务需求的准确匹配,在对制造云服务.流程节点任务.云服务的可组合性和流程匹配进行形式化描述的基础上,提出一种基于业务流程的制造云服务组合模型.该模型由业务流程引擎.业务流程.选择逻辑.评估逻辑.监控逻辑.知识库和原子云服务集构成,在功能匹配的基础上,对候选服务的可组合性进行检查,结合负载.服务质量(QoS)和业务流程信息,选择合适的云服务,并将其挂接在业务流程上实现制造云服务的

ISO文档管理——企业BPR的助手和驱动引擎

随着企业业务发展及与国际化接轨的要求,国内企业迫切需要采用成熟的ISO管理标准体系改善自身管理环节,提高管理水平,同时通过对自身管理体系的认证来给客户以信心和保证.因此目前国内企业对ISO 9000(质量管理体系).ISO 20000(IT服务管理体系).ISO 27001(信息安全管理体系)等先进管理体系的认证方兴未艾. 在各种ISO管理体系中,都需要对大量文档进行管理,包括: ·对文档生命期进行管理.任何管理体系都需要用文档定义各种规程.表单等,这些文档从就绪.公示.发布.生效.版本升级直到

异步操作和Web服务,第3部分:向Web服务添加业务语义

在这个系列的前面两部分,Holt Adams 解释了 Web 服务异步操作的相关性并讨论了一些构建异步服务的模式.现在,他要开始讲解三个新规范 ― Web 服务的业务流程执行语言(Business Process Execution Language for Web Services).Web 服务协调(Web Services Coordination)和 Web 服务事务(Web Services Transaction)― 并说明它们如何为 Web 服务开发者提供许多可能性.您将看到这三个

Safeco的复合应用模型

Safeco是一家总部位于西雅图的保险公司,它提供汽车.房屋和小企业保险业务.Safeco建设了一个全国性的代理商网络.调查表明,这些代理商高度认可公司目前的Web销售服务平台,认为它是业界最好的.这个平台前端用.NET开发,后端则是使用了多年的IMS应用系统. 2006年初,Safeco为了提升产品研发和业务流程运作水平,启动了SOA系统项目.即便仅从IT角度看,此项任务也是颇具挑战性的,因为我们每次启动的新产品.解决方案和流程优化项目往往都是独立的,缺乏对系统一致性和项目边界的精确度量.我们

构建SOA组合业务服务,第4部分

第4部分: 使用公共事件基础设施开发可测量的组合应用程序 本系列讨论如何开发组合应用程序来支持业务服务,本文是其中的第 4 部分.为了确定 组合应用程序是否满足所确定业务目标,应用程序需要为可测量的.本文讨论如何在基于公 共事件基础设施的三个可重用构件的帮助下开发可测量的组合应用程序.我们将从中了解为 什么需要构件,以及如何使用其对组合应用程序进行测量. 引言 WebSphere Integration Developer 和 WebSphere Process Server 将公共事件基 础设

Netflix Conductor:一个微服务编排工具

本文讲的是Netflix Conductor:一个微服务编排工具[译者的话]这篇文章介绍了Netflix Conductor,一个微服务编排工具,为微服务执行复杂业务流程提供了一种思路,希望对读者有一定的启发. [深圳站|3天烧脑式Kubernetes训练营]培训内容包括:Kubernetes概述.架构.日志和监控,部署.自动驾驶.服务发现.网络方案等核心机制分析,进阶篇--Kubernetes调度工作原理.资源管理及源码分析等. Netflix内容平台工程团队运行许多业务流程,这些业务流程是通

使用TinySpider实战抓取自己博客中的内容

因为做官网,没有内容,因此就想办法从OSChina中写的博客里弄点内容,这就要用到爬虫了. 然后就花了几分钟搞了一下,步骤如下: 第一步,写个方法抓目录: ? 1 2 3 4 5 6 7 8 9 10 11 public static void processCategory(String categoryId) {         Watcher watcher = new WatcherImpl();         Spider spider = new SpiderImpl();    

精简Linux系统管理工作的五个秘诀

在数据中心,Linux可以是一把双刃剑:它提供灵活性,但也有复杂的风险.幸运的是,您可以使用的工具库可以使Linux系统管理变得更加容易. 最近,新的工具出现来帮助管理员在Linux服务器管理的各个方面.例如,Red Hat Linux Enterprise(RHEL)7的更新使管理员能够更好地控制策略和安全性,以及管理Linux引导过程可作为新的工具. 熟悉这些工具和更多的精简管理流程. RHEL 7引导过程采用GRUB 2,systemd RHEL 7为曾经使用RHEL 6版本的管理员们引入