现在的位置: 首页 > 综合 > 正文

流程是变化的,流程引擎的代码是固定的,怎么办?

2013年12月09日 ⁄ 综合 ⁄ 共 4335字 ⁄ 字号 评论关闭

    做工作流系统设计,我们始终会遇到这样一个问题,我们通过流程设计器画出的流程图是很灵活的,是变化多端的,是不确定的,而我们后台用于处理流程的引擎的代码却是相对固定的,不变的,静态的,那么我们怎么很好的用静态的,固定的,不变的代码来处理灵活的,变化的,不确定的流程呢?

    一部分观点认为,流程图和流程引擎之间必须通过程序员在中间编程来解决这个矛盾,这样的话,流程设计器就不是面对最终企业用户,而是面对程序员的,企业用户只是一个流程的底层用户,而不是直接参与到流程设计过程的角色,这样让企业用户很不爽啊,为什么我要应用一个流程,非得请程序员来画图并编程才能够实现呢?   在JBPM的讨论群里面,很多朋友都在咨询这个问题,因为公司的客户提出的需求是,我们要自定义流程,我们不要你们程序员来设计流程图。我们要自己画流程图。呵呵

   从国内目前的技术水平来讲,把流程设计器开放给最终用户,并且流程引擎在流程运行过程中要做到全自动控制,技术人员不干预流程的运行,并非不可能的事情,通过对流程节点的状态位的控制,一个并不是很复杂的流程图是完全可以做到自动运行的,如果在一个节点中嵌入了微型的脚本控制代码,那么一个流程在运行过程中,要做到没有人工干预的情况下自动运行,更不是一件难事。。。。

   就我们目前掌握的技术来看,要实现一个自定义的工作流系统,其核心原理大致是下面的几点

1:采用一个最简洁的流程图XML描述文件,即没有加入任何XPDL或者JPDL的定义元素,流程图XML只存储流程图的拓扑结构,和流程相关联的表单和业务数据全部通过数据库的关联表来和流程关联,流程图本身并不存储任何业务数据和业务相关的ID

2:流程图XML的拓扑结构必须转换到数据库中保存,数据库的结构是基于链表的数据结构

3:对这些保存在数据库中的流程图,定义一组大概有30个基本流程操作SQL语句,这些SQL语句的用途大致分为如下几个类型(具体的SQL语句,请参考JWFDv0.96二次开发包中的org.jwfd.workflowDesigner.UItools.Database.mysql.FlowsSqlControlModule.java  这个类文件的代码和注释)

      启动,暂停,终止,挂起一个流程的SQL操作

       public boolean start_flow(String graphid, String flow_startup_time) {}

       public boolean  end_flow(String graphid) {}

       public boolean suspend_flow(String graphid) {}

       public void restart_flow(String graphid) {}

    流程节点状态管理类SQL操作,包括修改节点状态为未处理,正在处理,已经处理等状态的操作

       public boolean set_active_step(String step_id, String graph_id) {}

       public boolean set_overactived_step(String step_id, String graph_id) {}

       public boolean set_noactived_step(String step_id, String graph_id) {}

       public boolean is_overactived_steps(String step_id, String graph_id) {}

       public boolean is_notactived_steps(String step_id, String graph_id) {}

       public boolean is_actived_steps(String step_id, String graph_id) {}

       public void set_Actioned_times(String step_id, String graph_id,int j) {}

       public void Reset_visited(String graph_id) {}

       public void set_visited_times(String step_id, String graph_id, int j) {}

       public void set_join_time(String step_id, String graph_id, int j) {}

       public int get_join_times(String step_id, String graph_id) {}

    流程节点和连接线拓扑查询SQL操作,包括查询当前节点的所有前驱节点,所有后驱节点,本流程第一个节点,最后一个节点等等这些SQL操作

      public String return_FirstStep(String graph_id) {}

      public String return_LastStep(String graph_id) {}

      public String return_nextStep(String step_id, String graph_id) {}

      public String return_preStep(String step_id, String graph_id) {}

      public java.util.ArrayList return_nextSteps(String graph_id, String step_id) {}

      public java.util.ArrayList return_preSteps(String graph_id, String step_id) {}

      public String get_stepname(String stepid, String graphid) {}

      public String get_stepid(String stepname, String graphid) {}

      public java.util.ArrayList return_edges(String step_id, String graph_id) {}

      public String return_tostep(String edge_id, String graph_id) {

   流程单步回退算法,流程嵌入脚本控制机制要使用到的SQL操作

      public boolean is_rollback_step(String step_id,String graphid){}

      public int get_actioned_times(String step_id, String graph_id) {}

      public boolean cf_step_path(String step_id,String graphid){}

      public boolean set_JAP(String step_id,String graphid,int j){}

      public int get_JAP(String step_id,String graphid){}

      public String get_condition(String step_id, String graph_id) {}

      public String get_prop(String edge_id, String graph_id) {}

      public void set_rollback_times(String step_id, String graph_id, int j) {}

      public int get_rollback_times(String step_id, String graph_id) {}

      上述的SQL操作是建立在JWFD自定义的流程数据库结构的基础上,JWFD自定义流程数据库的结构,请下载这里的文档 http://download.csdn.net/source/3252766

  4:利用上面的SQL操作,编写一个基于图论算法的流程运行控制器,这个算法基于图论中的广度优先遍历算法,请大家参考  绿色封面  清华大学出版社 严蔚敏,吴伟民老师的数据结构(第二版) 1996年   本书第七章 155页  图论   请认真阅读本章节 ,请在培训学校里面培训JAVA编程的朋友们,抽空好好学习一下数据结构,这本书是我们学计算机专业的必修课,我给你们保证,肯定是有用的

        for(int i =0  i <当前节点的邻接点个数){ // for语句对应的应该就是单向分支
        这个FOR循环体是用来处理从流程开始节点开始分支的N个节点的,有多少个节点,就循环多少次
 
       if (该点是个前驱路由点) { // 做一次判断,保证节点不是离散的   
    
       if(该点的属性是分支类型){ //节点的物理类型
          if (该点没有被访问过) {//节点的状态类型   节点是否被访问过的状态值  应该被放在状态寄存器中
              设置访问次数加(从递归方法中获得的循环控制变量)
              返回
          }
          else if(如果已经访问过,但是访问次数<它的前驱节点总数){ // 节点的状态类型
               设置访问次数加(从递归方法中获得的循环控制变量+1)
               返回
          }
          else if(总计访问次数=它的前驱节点总数){ // 节点的状态类型
              递归进入下一个节点的访问(把大循环体的,循环变量带进去递归方法中)
          }
          }
          else if(如果是普通节点){ // 节点的物理类型
              设置访问标志
              递归进入下一个节点的访问(把大循环体的,循环变量带进去递归方法中)
          }
          }
   }

    

  5:   对每一个具体的流程图,上面的算法并不一定是完美的,估计有时候会做一些局部的修改,另外限于篇幅,我在这里就不详细介绍嵌入式脚本的使用了,具体请参考我在JWFD设计文档包中的文档

 6: 估计在一个用户自定义流程系统上线之后,程序员还是要根据具体的业务情况,修改一下这个流程系统,尽量的满足用户的需求。。。。。。

        遇到有什么具体的问题,可以给我发邮件   comsci@163.com     

抱歉!评论已关闭.