[原创]JWFDv0.96工作流引擎设计-自动运行控制器结构说明.

                 JWFDv0.96---工作流引擎设计
                               --自动运行控制器结构说明



 

总体设计思路

 

 

  通过建立JWFD 开源工作流系统自定义的流程拓扑数学模型,并在此模型的基础上面构建一系列的 SQL-API 原子操作函数,同时结合图形广度优先遍历算法的变异体,构建出一个流程自动运行控制器

 

 

  用户对一个流程实例的操控均建立在这个自动运行控制器的基础上面,至于客户端,呵呵,各位朋友就自己实现吧,越俎代庖的事情我就不做了,开源项目要避免和商业产品形成竞争,毕竟这个行业的整体发展主要要靠广大的商业软件企业,comsci 仅仅是一个衬托,呵呵

 

 

 

 

实现的技术与方法

 

 

蓝色字体标注的函数均为 JWFD自定义的流程基础操作函数,这些函数的详细说明请参考

 

 

JWFDv0.96 工作流系统开发包简易说明 .doc

 

 

JWFDv0.96 工作流引擎设计 - 数据库结构说明 .doc

 

 

JWFDv0.96 流程 XML 结构说明 .doc

 

 

 

 

 

 

 

这个算法中使用的原子操作函数,均是 JWFD对流程拓扑结构进行数据库建模之后,在这个模型基础上形成的基础操作函数,关于这些函数的详细说明和数据库结构说明请参考 JWFD开发 API 简易说明 JWFD工作流引擎数据库结构说明 文档,下载地址在 http://www.cnblogs.com/comsci/favorite/260690.html

 

 

 

 

 下面我们就来分析这个运行控制器的结构,并试图划分出几个主要的功能模块,然后对此进行理解和再构造,在这之前,需要先回顾一下 JWFDV0.94引擎的 DFS 自动运行控制器的算法结构,事实上 DFS 是一个全自动的运行控制器,而 SAN 是一个半自动的控制器,所谓全自动既指流程在运行过程中的流转过程全部由计算机通过 DFS 算法来控制,中间不需要人为地干预,而半自动的意思是流程在流转过程中,需要通过节点操作者的触发来推动流程的流转,但是 SAN 算法却在并行控制和条件会签,单步回退这些功能上面均实现了自动化的处理,所有这些复杂的逻辑判断均不需要人工来处理,所以这里的自动化是指流程的流转的控制是由机器来控制还是由人和机器共同控制,但是要真正做到全自动化流程控制,引擎系统就需要采用人工智能的模型,目前我们的技术水平还没有达到这个程度,但是这是我们努力的方向,争取 JWFD 能够在 1.0 版本的时候使用人工智能技术设计流程引擎

 

 

 

SAN 算法的前身是Jwfd v0.94 版本的运行控制器  DFS 算法,该算法所在的类模块是JWFDv0.94 代码包 org.jwfd.workflowEngines.GXLFlowControlModule.java

这个 DFS算法的结构大体如下,为方便理解 SAN 算法,我把 DFS 算法的结构也写出来

 

 

--------------------------------------------------------------------------- 

 

     for(int i =0  i <  当前节点的邻接点个数){

 

        if (该点是个前驱路由点) {

            if (该点没有被访问过) {

                  设置访问次数加(从递归方法中获得的循环控制变量)

                  返回

              }

            else if( 如果已经访问过,但是访问次数<它的前驱节点总数){

                   设置访问次数加(从递归方法中获得的循环控制变量+1)

                   返回

              }

            else if(总计访问次数=它的前驱节点总数){

               递归进入下一个节点的访问(把大循环体的,循环变量带进去递归方法中)

              }

 

              }

            else if(如果是普通节点){

               设置访问标志

               递归进入下一个节点的访问(把大循环体的,循环变量带进去递归方法中)

              }

              }

       }

 

 -----------------------------------------------------------------------------------------------

 

 

需要注意的是,这个DFS 控制器算法的主要模块均是通过条件判断来划分的,因此这种结构和规则引擎的设计思路有些类似,可以说是规则引擎的简化实现,一个流程引擎的运行控制器可以依赖规则引擎来构建,但是如果朋友们愿意自己动手 DIY ,那么用最底层的 JAVA 语言来构建一个运行控制器,将大大有利于今后的长远发展。。。。 

 

 

DFS算法的模块主要是由节点的属性 - 是否是汇聚或者普通节点来划分,而 SAN 算法则是由节点的处理状态来划分的

 

 

 

SAN基础架构仍然采用图论中的广度优先算法的变异结构,但是这个版本中增加了引擎自动对流程的条件汇聚的判断和处理,增加了自动并行分支和节点单步回退的功能模块,所以这个算法的语句要比 DFS 算法语句多出一倍,但是整体的逻辑结构基本上还是可以划分为三个主要的状态判断和处理逻辑单元,第一个单元式当前节点的未处理状态,第二个单元是当前节点的正在处理的状态,第三个单元式当前节点的处理完毕的状态,下面的代码解释中,用红色的字体划分了这三个主要的单元部分

 

 

这个运行控制器的整个结构大体如下伪码所表示的,一个FOR 循环体内部嵌入三个 IF 判断体,每个判断中包括若干个对应的处理模块和一个递归模块,其中递归模块是用来推动流程向前流转的动力源,由于这个版本中加入了回退处理和条件汇聚的处理模块,所以判断处理单元的结构相对 DFS 算法要复杂一些,请对比 v0.94 DFS 算法结构,这样更加便于读者理解 JWFD 流程自动运行控制器的设计思路,并由此设计出自己的引擎控制模块

 

 

 

---------------------------------------SAN伪码描述 -----------------------------------------------------  

 

FOR循环体 ( 循环控制变量为存储节点的链表容量 )

 

IF   当前节点尚未处理

    嵌入处理过程

     递归 前进  

 

 

ELSE IF  当前节点处理完毕

    嵌入处理过程

     递归 前进

 

 

ELSE IF  当前节点正在处理     

    嵌入处理过程

     递归 前进

 

 

--------------------------------------------------------------------------------------------

 

 

   下面是SAN 自动控制器代码的说明,如果朋友们懒得看这些代码,可以直接打开 JWFDv0.96 for Eclipse 的代码,直接运行这个 SAN 函数 ( ) ,只需要按照下面的提示进行操作就可以简略的体会一下运行一个流程实例的过程

 

 

 

 * 1: 使用流程设计器画出流程
 * 2: 将流程图导入到数据库中 ( 默认 MYSQL)
 * 3: 使用数据库管理工具查看流程数据是否正确导入
 * 4: 参考数据库设计文档,了解数据库结构
 * 5: 把流程实例名导入下面的方法中
 * 6: 启动流程调试函数 action()

 

如果大家需要深入的学习和了解这个运行控制器的结构,那抽空看看代码和说明,相信会有所感悟

 

 

 

   具体的实现代码如下,每行均带有详细的说明 

 

 

 --------------------------------------算法开始 -----------------------------------------------------

 

 

 public void  SAN  (java.util.ArrayList  ln , String  gra p hid ,String  prestep ) {  

 

 

函数的三个参数分别是:存储当前流程节点的链表 ln ,当前流程图实例 id -graphid,   当前流程节点的前驱节点prestep

  

 java.util.ArrayList lln = new java.util.ArrayList() ;  

 新创建一个流程节点链表存储

 

if (!ln.isEmpty()) {      

 

这句的含义是判断当前节点变量链表存储器是否为空 ,ln 链表数据是从 SAN 函数中传递过来的,该链表用于存储正在处于待处理的流程节点

 

 

 

      for (int i = 0; i < ln.size(); i++) {   

      这一句的意义是FOR 循环贯穿整个运行控制器算法,作为流程引擎的并行处理的关键语句

          for循环的控制条件中ln.size()存储的是当前流程图的节点序列

 

 

--------------------------------------------------------------------------------------------

下面这个if 判断是整个运行控制器的三个关键判断单元的第一个,这个判断和判断体的处理部分是判断当前流程节点是否处于尚未处理的状态,然后根据这个判断来进行一系列的处理

---------------------------------------------------------------------------------------------

 

 

      if ( stm.is_notactived_steps (ln.get(i).toString(), graphid)) {  

 

这句的含义是判断当前流程节点是否处于尚未处理的状态,以此作为是否进入下一步流程节点操作环节的依据,这个判断和判断体的处理过程是整个运行控制器算法的第一个关键部分

         

        ftc.set_startup_time (ln.get(i).toString(), graphid);   这句是时间设置函数,用于设置当前节点的初始操作时间点,该时间参数可以作为引擎系统对流程进行统计的时间控制参数和依据

 

 

          stm.set_active_step (ln.get(i).toString(), graphid);   这句的含义是将节点设置为正在活动状态,既激活当前节点,使之成为待处理节点          

 

        stm.set_visited_times (ln.get(i).toString(),graphid,stm.get_visited_times(ln.get(i).toString(), graphid) +1);这句的含义是设置节点的被流程引擎访问的次数 ( 取节点表中的访问次数值 +1)

 

       if ( stm.is_actived_steps (ln.get(i).toString(), graphid)) {  

            上面这句用于 判断当前节点是否已经被处理

           

            System.out.println(ln.get(i).toString() + "调用客户端 ");

        上面这句是个屏幕显示输出,用于流程调试的时候使用

 

 

 

            this. action_step (ln,ln.get(i).toString(),graphid,prestep,this);   

这一句用来调用节点处理界面,用户在该界面中对节点进行操作,该节点对应的后台数据库的状态值就发生变化 ..action_step()函数是一个 SWING 的简易流程运行处理界面

 

           }

 

 

         }

 

 

---------------------------------------------------------------------------------------------

 

下面这个if 判断是整个运行控制器的三个关键判断单元的第二个,这个判断和判断体的处理部分是判断当前流程节点是否处于已经处理完毕的状态,然后根据这个判断来进行一系列的处理

----------------------------------------------------------------------------------------------

 

         else if ( stm.is_overactived_steps (ln.get(i).toString(), graphid)) { 这一句用于判断节点是否已经是处理完成的状态,这个判断和判断体的处理过程是整个运行控制器算法的第二个关键部分

 

    

            if ( stm.return_preSteps (graphid, ln.get(i).toString()).size() > 1) {

               上面这句用于 判断当前节点是否是汇聚节点

 

        if ( join_less (ln.get(i).toString(), graphid)) {      

 

这里是个重要的汇聚处理过程,判断汇聚点的汇聚次数是否小于已处理的次数,以此作为流程流程到下一节点的依据 join_less() 函数的结构,请参考 JWFD 流程运行控制器 API 说明

 

 

            if(prestep.equals(ln.get(i).toString())){    

  

 这句表示这个地方增加个控制条件,如果前驱与当前点一致,那么就意味着引擎对该节点重复访问了,需要进行阻塞控制

 

 

 

      System.out.println(ln.get(i).toString() + "空操作 ");   

 

             上面这句是个屏幕显示输出,用于流程调试的时候使用

 

 

                  这个IF 控制体是 输出空操作--- 用于防止汇聚点自循环访问

                    

               }else{

 

          System.out.println(ln.get(i).toString() + "汇聚点再次调用客户端 ");

 

    上面这句是个屏幕显示输出,用于流程调试的时候使用

 

 

        下面这句表示 将汇聚点作为当期节点参数送入节点处理界面进行处理

 

         run_action (ln,ln.get(i).toString(),graphid,prestep,this);       

                 }

            }

 

 

 

 else if  (join_equals (ln.get(i).toString(), graphid)) {  

 

 

这句表示这里是第二个重要的汇聚处理过程,判断汇聚点的汇聚次数是否等于已处理的次数,以此作为流程流程到下一节点的依据、 join_less() 函数的结构,请参考 JWFD - API简易说明

           

下面这句用于判断节点已访问次数是否等于节点活动次数加上节点的回退次数

if( stm.get_visited_times (ln.get(i).toString(),graphid)==stm. get_actioned_times (ln.get(i).toString(),graphid)+ stm.get_rollback_times (ln.get(i).toString(), graphid))

             { 

System.out.println(ln.get(i).toString() + "汇聚完成处理完成进入递归 , 处理下个节点 ");

 

上面这句是个屏幕显示输出,用于流程调试的时候使用

 

     run_next (lln,ln.get(i).toString(),graphid);      

    这句的含义 如果上述判断相等,那么启动递归过程,流程进入下一个节点开始进行下一步流转

                     

    }else if( is_rollback (ln.get(i).toString(),prestep,graphid)){ 这句是 v0.96 版本新

 

 

      System.out.println(ln.get(i).toString() + "汇聚点经过回退后再次调用客户端 ");

    上面这句是个屏幕显示输出,用于流程调试的时候使用

 

 

          run_action (ln,ln.get(i).toString(),graphid,prestep,this);  这句表示如果节点被回退,那么再次调用节点处理界面进行处理

             }

           }

         }

         else if ( stm.return_preSteps (graphid, ln.get(i).toString()).size() ==1) {   如果当前节点是普通的节点,那么直接通过递归进入下一个节点进行处理

          

           System.out.println(ln.get(i).toString() + "普通进入递归 , 处理下个节点 ");

       上面这句是个屏幕显示输出,用于流程调试的时候使用

 

 

            run_next (lln,ln.get(i).toString(),graphid);  当前 ( 普通 ) 节点已经处理完毕,调用 run_next() 递归函数使得引擎开始处理下一个节点,凡是出现 run_next() 函数的地方,均表示当前节点处理完毕,准备进入下一个节点的处理环节

 

         }

        }

 

 

 

 

 

----------------------------------------------------------------------------------------------------------------------  

下面这个if 判断是整个运行控制器的三个关键判断单元的第三个,这个判断和判断体的处理部分是判断 当前流程节点是否处于正在处理状态 ,然后根据这个判断来进行一系列的处理

----------------------------------------------------------------------------------------------------------------------  

        

 

   else    if ( stm.is_actived_steps (ln.get(i).toString(), graphid)) {  判断当前流程节点是否处于正在处理状态 , 这个判断和判断体的处理过程是整个运行控制器算法的第三个关键部分 is_actived_steps()函数的操作,请参考 org.jwfd.workflowDesigner.UItools.Database.mysql.FlowsSqlControlModule.java类的 695 行的详细说明

 

         判断当前节点的是否是汇聚节点

        if ( stm.return_preSteps (graphid, ln.get(i).toString()).size() > 1) {  

        

         如果汇聚的次数和处理的次数相等,那么执行一次空处理                      

           if  (join_equals (ln.get(i).toString(), graphid)) {  

           

              System.out.println("空控制体 ");

          这句是屏幕显示输出,用于流程调试的时候使用

 

             }

 

           else if (join_less (ln.get(i).toString(), graphid))    

如果处理次数少于汇聚次数,则引擎需要再次对流程的汇聚进行处理,然后才能进入递归调用

             {

            System.out.println(ln.get(i).toString() + "汇聚点再次处理 ");

        上面这句是个屏幕显示输出,用于流程调试的时候使用

 

             run_action (ln,ln.get(i).toString(),graphid,prestep,this);

 

            }

          }

        }

      }

    }

 

  }

 

  -------------------------------------- 算法结束 -----------------------------------------

 

可以这样认为,这个SAN 算法是 JWFD 流程系统的一个核心部分,正是由于有这个算法的存在,才使得 JWFD 和其它的流程系统不太一样, JWFD 可以轻易的部署到最终用户那里,也就是说 JWFD 不需要用户进行二次开发就可以直接使用,由于有 SAN 算法的自动控制机制才使得最终用户完全不需要考虑流程如何流转,仅仅是需要使用设计器设计出一个流程, SAN 算法及其附属模块就可以自动控制流程的流转。虽然目前这个算法还不是很完善,但是毕竟为我们开发出自动流程系统提供了一个很好的参考和方向

 

 

你可能感兴趣的:(数据结构,工作,mysql,算法,嵌入式)