博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Slickflow.NET 开源工作流引擎基础介绍(二) -- 引擎组件和业务系统的集成
阅读量:5058 次
发布时间:2019-06-12

本文共 4416 字,大约阅读时间需要 14 分钟。

  1. 集成流程引擎的必要性

    业务过程的变化是在BPM系统中常见的现象,企业管理层需要不断优化组织架构,改造业务流程,不可避免地带来了业务流程的变化,企业信息系统就会随之面临重构的可能性。一种直接的方式是改造业务代码,适应业务过程的变化,这将会面临不断改写代码的需求;还有一种方式是使用流程引擎控制业务过程的变化,将改写业务代码的操作交由流程引擎,通过流程引擎解析业务规则,驱动业务过程流转,从而将改写业务代码的可能性降到最低。

    显而易见,流程引擎带来的好处是为了更好解决业务过程变化后带来的重构风险,信息系统如果是柔性的,可伸缩,可动态适应的,那么它才可以保持不被很快被替代的可能性,自然就能够为企业降低不断升级或实施产生的成本费用。

  2. 业务系统和流程引擎的交互方式

    业务系统中嵌入流程引擎中间件,是一种常见而直接的方式;虽然有些引擎组件能够配置业务模块的反射接口,但是我们目前认为比较合理的方式是:流程引擎不应过多地绑定业务接口,因为业务接口的变化是始终不可避免,会一直发生的,而引擎组件同样需要保持稳定。

    通常在业务模块中,当处理业务功能后,也会调用引擎组件的服务接口,驱动业务流程流转。我们一直把业务变化部分交由业务过程的服务处理,流程引擎中间件始终只处理解析规则,驱动流转的职责。这样可以避免引擎组件的功能膨胀,保持引擎组件的灵巧。

    常见的业务过程调用流程引擎服务接口的图示:

    Step 1:  当前正在执行功能单元发起的调用

    Step 2:  执行完毕,下一步已经处在等待中的功能单元

  3. 流程引擎中间件集成方式的优势

    首先,流程引擎中间件的职责是解析业务规则,驱动业务过程运转。人们不断地将引擎功能封装为组件,从而方便业务模块的调用。将最复杂,最容易变化的部分交由引擎中间件处理,才可以让用户更加专注于业务功能的实现。将引擎组件的功能从业务模块中分离出来,整体上降低了整个系统的复杂程度,使业务系统变得更加容易维护。

    其次,流程引擎中间件提供动态组件引用,以及WebService访问;可以满足多种架构系统的集成需求。在当前互联网云端模式的软件架构盛行的模式下,中间件可以以WebService方式提供Restful的API接口,使得引擎提供的服务能够跨越系统结构,组织边界来驱动业务过程流转,这种分布式的模式极大地发挥了引擎中间件的功能效用。

  4. 代码示例

    以下代码演示业务类(生产订单)如何集成工作流引擎并调用服务接口的过程。

  4.1 实现IWfServiceRegister接口

///     /// 工作流注册接口    ///     public interface IWfServiceRegister    {        WfAppRunner WfAppRunner { get; set; }        void RegisterWfAppRunner(WfAppRunner runner);    }

  4.2 接口实现代码示例

///     /// 生产订单服务    /// 示例代码,请勿直接作为生产项目代码使用。    ///     public partial class ProductOrderService : ServiceBase, IProductOrderService, IWfServiceRegister    {        #region IWorkflowRegister members        public WfAppRunner WfAppRunner        {            get;            set;        }        public void RegisterWfAppRunner(WfAppRunner runner)        {            WfAppRunner = runner;        }        #endregion    }

  4.3 业务调用示例

  1) WfService服务接口注册

IWfServiceRegister sr = ProductOrderService as IWfServiceRegister;    sr.RegisterWfAppRunner(runner);    WfAppResult appResult = ProductOrderService.Sample(productOrder);     //此处调用业务类的节点方法,内部有流程交互代码。    if (appResult.Status == 1)        result = ResponseResult.Success("打样操作成功!");    else        result = ResponseResult.Error(string.Format("打样操作失败:{0}", appResult.Message));

  2) 业务类方法实现

///     /// 打样    ///     ///     public WfAppResult Sample(ProductOrderEntity entity)    {        var appResult = WfAppResult.Default();        var wfas = new WfAppInteropService();        var session = SessionFactory.CreateSession();        try        {            session.BeginTrans();            //流程运行            var result = wfas.RunProcess(session, WfAppRunner, WfAppRunner.Conditions);    //流程交互类调用            if (result.Status == WfExecutedStatus.Success)            {                //写步骤记录表                Write(session, WfAppRunner, "打样", entity.ID.ToString(), entity.OrderCode, "完成打样");                //业务数据处理部分,此处是简单示例...                UpdateStatus(entity.ID, (short)ProductOrderStatusEnum.Sampled, session);                session.Commit();                appResult = WfAppResult.Success();            }            else            {                session.Rollback();                appResult = WfAppResult.Error(result.Message);            }        }        catch (System.Exception ex)        {            session.Rollback();            appResult = WfAppResult.Error(ex.Message);        }        finally        {            session.Dispose();        }        return appResult;    }

  4.4 流程应用交互API封装

///     /// 工作流运行    ///     ///     ///     /// 
public WfExecutedResult RunProcess(IDbSession session, WfAppRunner runner, IDictionary
conditions = null) { var result = new WfExecutedResult(); var wfService = new WorkflowService(); var nodeViewList = wfService.GetNextActivityTree(runner, conditions).ToList
(); foreach (var node in nodeViewList) { var performerList = wfService.GetPerformerList(node); //根据节点角色定义,读取执行者列表 Dictionary
dict = new Dictionary
(); dict.Add(node.ActivityGUID, performerList); runner.NextActivityPerformers = dict; if (node.IsSkipTo == true) //特定节点上的判断处理 { result = wfService.JumpProcess(session.Connection, runner, session.Transaction); } else { result = wfService.RunProcessApp(session.Connection, runner, session.Transaction); } } return result; }

转载于:https://www.cnblogs.com/slickflow/p/5032122.html

你可能感兴趣的文章
基于grunt构建的前端集成开发环境
查看>>
MySQL服务读取参数文件my.cnf的规律研究探索
查看>>
java string(转)
查看>>
__all__有趣的属性
查看>>
BZOJ 5180 [Baltic2016]Cities(斯坦纳树)
查看>>
写博客
查看>>
利用循环播放dataurl的视频来防止锁屏:NoSleep.js
查看>>
python3 生成器与迭代器
查看>>
java编写提升性能的代码
查看>>
ios封装静态库技巧两则
查看>>
Educational Codeforces Round 46 (Rated for Div. 2)
查看>>
Abstract Factory Pattern
查看>>
C# 实现Bresenham算法(vs2010)
查看>>
基于iSCSI的SQL Server 2012群集测试(一)--SQL群集安装
查看>>
list 容器 排序函数.xml
查看>>
存储开头结尾使用begin tran,rollback tran作用?
查看>>
Activity启动过程中获取组件宽高的五种方式
查看>>
java导出Excel表格简单的方法
查看>>
SQLite数据库简介
查看>>
利用堆实现堆排序&优先队列
查看>>