zoukankan      html  css  js  c++  java
  • 工作流引擎下基于表达式Tree复杂验证的实现

    工作流引擎下基于表达式Tree复杂验证的实现

     

    在工作流开发中,用户根据Form模板引擎自定义Form表单时,需要动态定义对Form表单中的值进行验证来控制来验证用户的输入。

    Form表单字段验证无法就是长度,是否为空,格式是否正确等等,这些我们可以通过在创建Form表单时,根据控件(自定义各种Form控件)的类型来验证。不过这只能对Form表单进行控制,如果要动态控制Form表单所关联的业务逻辑呢?这时,我们就应该分析业务逻辑。在一般的业务逻辑进行验证时,一般就涉及比较运算符(<>>=<==)和算法运算符(+-*/)的验证。这就需要基于表达式的验证方式。

    场景:假如用户在定义工资表单(Wage Form)时,有一个工资的表单框txtWage,如果要实现员工工资(类别:初级软件工程师)满足两种条件:

    (1)最低工资不能低于1500 

    2)基本工资*工资系数1.1(不固定)+项目奖金500(不固定)不能超过4000

    仔细分析,就可以看出:

    上面的两个条件可以等价位 : Wage>=1500&&Wage*1.1+500<=4000

    那么如果直观的实现上面的表达式,而又方便修改、删除等操作。根据我们学的数据结构就会联想到二叉树,也就是基于树的实现。问题有来了,如何实现树的结构呢,而又能够方便修改,添加等操作。首先想到了TreeView控件,但发现TreeView控件不能编辑和自定义添加和修改标签。这是只能考虑自己构建树的结构。下面来看一下,我在工作流引擎中实现的一个Demo


    上面图片实现了树的收缩、展开、表达式的自定义,支持嵌套定义表达式,通过弹出创建窗口(或者DIV层)来实现,弹出窗口包括数据类型,source定义(表达式左边),target定义(表达式右边)。每一个FieldValidation可以包括多个Expression,这多个Expression之间可以是&&或者 || 等操作,最顶层的Expression是比较运算符操作,子Expression是算术运算符操作。

           那么上面数据结构式如果实现的呢?仔细发现其实就是一个标准二叉树结构。相当于有三种节点类型:ExpressionSourceTarget,我们可以用一个字段来标识这三种类型。这种方式最容易实现。但在我们的项目功能设计时,数据结构已经设计好了,是通过对象List集合嵌套来定义。Validation 类,Expression类、Leaf类。Validation有一个ExpressionList集合, Expression类中有一个Leaf类型的Source属性和一个Leaf型的Targe属性,同时有一个Parent字段来标识他的父节点,而Leaf类有一个Expression类型的属性Expression,用来关联子Expression,同时也有一个Parent字段来标识他的父节点Expression

         接下来要实现树的遍历就涉及到树的遍历:递归查找父节点、子节点、递归获取某一个Expression的层次(限制Expression深度为5)。而在递归上面,我纠结了很几天,总是出现各种错误,最终还是通过理解递归原理来实现的。要递归实现:首先要找到出口:也就是当程序满足某种条件时就跳出函数,返回其查找的值。在递归时,函数中局部变量是通过栈的方式保存起来。

    先来看一个获得某一个Expression的深度的方法。  


    假如上面的图片中树中第一顶层ExpressionTarget有一个子Expression(节点4),如果要获得这个ExpressionLevel,栈中的结构是怎么样的呢? 首先从节点一开始,发现exp1RefNo=RefNo,此时temp=1,继续递归下去,直到节点3,,还没有找到,然后就开始回溯。此时栈中结构。

    Exp3

    Exp2

    Exp1

    栈底

    Temp3=3

    Temp2=2

    Temp1=1

    栈底

    当节点3RefNo=RefNo不成立时,Exp3Temp3出栈;就回溯到节点2,发现节点2 targe也不满足要求,Exp2 Temp2出栈;回溯到节点1,然后执行节点1target节点,发现targe.Expression.RefNo==RefNo 如是就记录Expression_Levl=temp+1=2,然后跳出循环。Expression_Levl就是要获取的值。

           在软件开发中,树、表达式、递归是经常会用到的,层级菜单的创建,权限的设计等等,都会设计树、递归,其实只要掌握了递归的原理,一切都会迎刃而解的。

        下一篇:基于微软 ResourceProvider机制多语言的实现。

  • 相关阅读:
    VS2012打开项目 提示Asp.net4.5未在web服务器上注册
    asp.net使用qq邮箱发送邮件
    Reflect(反射)
    c#创建windows服务
    Lambda(Linq)
    iis部署wcf服务过程
    剑指offer面试题 滑动窗口的最大值
    剑指offer面试题68 树中两个节点的最低公共祖先(java实现)
    Spring4基础 学习笔记(3) AOP(1) 基于Xml
    Spring4基础 学习笔记(1) Bean
  • 原文地址:https://www.cnblogs.com/hubcarl/p/1968824.html
Copyright © 2011-2022 走看看