公司主页 投诉建议 专家网 Bug登记 需求管理 客户服务网

中联论坛

查看: 569|回复: 24

[分享] 规则引擎应用注意事项

[复制链接]

该用户从未签到

发表于 2020-4-18 14:33:15 | 显示全部楼层 |阅读模式
扫描关注微中联,带你进入中联人的微世界
背景
      在BH构建的过程中,为提高构建者的开发效率、同时也是规范构建行为,想封装一些公共的基础方法供构建者使用,想到了以下两种方法:
     1.通过公共逻辑块封装基础方法
     2.通过规则封装基础方法
     在验证通过规则封装基础方法的时候,发现执行效率不高,与大家分享下验证过程中遇到的一些问题。
验证过程
     本来为满足用户个性化的业务流程控制需求,敏捷提供了规则管理功能,但在应用过程中需要注意应用环境,我们先看两个应用效果对比
    一.实现1加10000的和
       1.通过规则实现
  1. var aa = 0;
  2. for (i = 1;i<=10000;i++)
  3. {
  4.         aa = aa+i;
  5. }
  6. 结果= aa;
复制代码

       2.通过BH表达式实现
  1. decimal num =0;
  2. for (int i =1;i<=10000;i++)
  3. {
  4.         num = num+i;
  5. }
  6. return num;
复制代码
      第一次执行结果如下图:
       1.1.png
       第二次执行结果如下图:
       1.2.png
       第一次执行结果:执行效率差距接近3倍,
       第二次执行结果:表达式的执行效率就高多了

    二.通过出生日期计算年龄
       1.通过规则实现
  1. var dtNow = new Date(当前日期.replace(/-/g,"/"));
  2. var dtBirthday = new Date(出生日期.replace(/-/g,"/"));
  3. 年龄='';
  4. if (dtNow.getTime() - dtBirthday.getTime() <= 0)
  5. {
  6.         return '';
  7. }

  8. //计算天数
  9. var intDay = dtNow.getDate() -dtBirthday.getDate();

  10. if (intDay < 0)
  11. {
  12.         var Month = dtNow.getMonth();
  13.     if (Month == 1)
  14.    {
  15.        Month = 12;
  16.            dtNow.setFullYear(dtNow.getFullYear() - 1);
  17.     }
  18.     else
  19.         {
  20.        Month = Month - 1;
  21.     }
  22.         dtNow.setMonth(Month);
  23.        
  24.         intDay = intDay + new Date(dtNow.getFullYear(), dtNow.getMonth(), 0).getDate();
  25. }

  26. //计算月数
  27. var intMonth = dtNow.getMonth() -dtBirthday.getMonth();
  28. if (intMonth < 0)
  29. {
  30.     intMonth += 12;
  31.     dtNow.setFullYear(dtNow.getFullYear() - 1);
  32. }

  33. //计算年数
  34. var intYear = dtNow.getFullYear() - dtBirthday.getFullYear();

  35. /*格式化年龄输出*/
  36. if (intYear >=1)
  37. {
  38.         年龄 = intYear+'岁';
  39. }
  40. if (intMonth >0 && intYear<=5)
  41. {
  42.         年龄 = 年龄 + intMonth+'月';
  43. }
  44. if (intDay >=0 && intYear<1)
  45. {
  46.         if (年龄.Length == 0 || intDay > 0)
  47.         {
  48.         年龄 = 年龄 + intDay+'天';
  49.     }
  50. }
复制代码

       2.通过BH表达式实现
  1. DateTime dtNow = 服务器时间();
  2. DateTime dtBirthday = Convert.ToDateTime("2020-01-01");
  3. int intDay;
  4. int intMonth;
  5. int intYear;
  6. string strAge;

  7. intDay = dtNow.Day - dtBirthday.Day;
  8. if (intDay < 0)
  9. {
  10.         dtNow = dtNow.AddMonths(-1);
  11.         intDay += DateTime.DaysInMonth(dtNow.Year, dtNow.Month);
  12. }

  13. intMonth = dtNow.Month - dtBirthday.Month;
  14. if (intMonth < 0)
  15. {
  16.         intMonth += 12;
  17.         dtNow = dtNow.AddYears(-1);
  18. }      

  19. intYear = dtNow.Year - dtBirthday.Year;   
  20. {
  21.         strAge = intYear.ToString() + "岁";
  22. }  

  23. {
  24.         strAge += intMonth.ToString() + "月";
  25. }      

  26. {
  27.         if (strAge.Length == 0 || intDay > 0)
  28.         {
  29.                 strAge += intDay.ToString() + "日";
  30.         }
  31. }      

  32. return strAge;   
复制代码

       第一次执行结果如下图:

       2.1.png

       第二次执行结果如下图:

       2.2.png

       从上面第一次执行结果可以看出通过调用规则与通过表达式的执行效率差距还是挺大的,同时我们的规则应用场景大多是在第一次加载程序时使用


总结
        1.规则中的JAVASCRIPT脚本不适合写复杂的数据处理,特别是循环处理,性能消耗较大
        2.规则中相对简单的方法(类似于通过出生日期计算年龄),通过规则实现与通过表达式实现也有一定性能差距
        3.规则一般应用在简单的业务逻辑控制上,应避免复杂的业务逻辑处理,同时也不便调试及问题查找
        4.规则为何较消耗性能,还需敏捷的同事看看能否有优化或改进的空间




点评

【鼓励帖】验证过程详细,有一定借鉴和启发意义。  发表于 2020-4-22 10:45
回复

使用道具 举报

该用户从未签到

发表于 2020-4-19 16:23:23 | 显示全部楼层
基于微信公众号的客户服务系统
1、提供公共的基础方法很有必要性,区卫也在做相同的事;
2、规则引擎的作用本身应或许不是用于写公共逻辑。所以公共方法的提供思路还是应使用公用逻辑块。
3、但如果公用逻辑块存在哪些不足可以提出来,让敏捷进行改进;
回复 支持 1 反对 0

使用道具 举报

  • TA的每日心情
    开心
    2019-10-19 18:50
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    发表于 2020-4-19 00:02:07 | 显示全部楼层
    我的理解是,这个可能叫通用函数比较合理一点,规则引擎一般是处理比较复杂的逻辑且能自定义的,楼主这个还不能算得上是规则引擎。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2020-4-19 09:41:43 | 显示全部楼层
    扫描关注微中联,带你进入中联人的微世界
    关于调试,规则引擎中有输出过程信息的函数,表达式好像是没得的,相对来讲规则引擎好像更方便调试样。但规则引擎有个弊端的是,只能退出编辑后,到管理界面去运行调试,这点希望敏捷的同事可以优化下,可以直接在编辑界面运行调试,这样易用性就更好了。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-1-28 10:40
  • 签到天数: 62 天

    [LV.6]常住居民II

    发表于 2020-4-19 20:31:10 | 显示全部楼层
    基于微信公众号的客户服务系统
    规则我的理解,根据医院情况做不同的限制大致分3种,例如某种功能是否启用(CA签名,数据上传),某些功能控制时效(挂号有效天数,处方有效天数…),以及简单if...else分支选择(比如某电生理项目:胎心监测在胎心室做,其余的在心电室做)。像带有计算性质,复杂运算,正则表达式都不适用于规则,复杂不美观,毕竟是直面用户的,规则太复杂对维护人员不太友好。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-5-10 06:04
  • 签到天数: 61 天

    [LV.6]常住居民II

    发表于 2020-4-26 07:19:12 | 显示全部楼层
    区卫合理费用也使用规则引擎,主要是解决医保目录限用规则的问题。医保限用规则种类多,数量大,变动也比较频繁,因而把医保限用规则中的相关判断抽取成单一逻辑判断,再通过与或非组成组合逻辑判定式。单一判断是通过JavaScrip脚本来实现的,通过JS脚本实现的好处就是这个脚本可以通过一个定制界面来自动生成,c#调用js引擎来动态生成单一判断的输出结果,输出结果和组合规则逻辑判定式运行逻辑运行,得出是否可用相关医保目录的结论。从而达到动态对医保限用规则调整的目的。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2016-8-9 08:59
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2020-4-27 11:54:57 | 显示全部楼层
    扫描关注微中联,带你进入中联人的微世界
    哪些情况下使用规则,哪些情况下建议使用公用逻辑块?当时设计的时候,是出于怎么的考虑?希望敏捷的同事科普一下
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2020-6-18 18:29
  • 签到天数: 74 天

    [LV.6]常住居民II

    发表于 2020-4-30 09:08:41 | 显示全部楼层
    基于微信公众号的客户服务系统
    在我的理解中规则引擎有点类似于一个写公用函数的地方,可以用来写一些简单的逻辑来判断,但是在楼主
    的验证后看来以后逻辑复杂的地方还是要慎用,这样我对规则引擎的使用时机有点迷糊了,希望清楚的同事
    能够简单解释一下。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-12-25 15:21
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2020-4-30 15:25:26 | 显示全部楼层
    对于规则引擎的应用目前我们也只是用作参数设置,比如不同的医院对某些字段的控制要求不一样,我们可以直接在参数设置简单的值,然后具体的实现处理逻辑还是放在逻辑块或操作过程去判断处理,还没试过在规则里面设置复杂的表达式计算。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-10-19 10:06
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2020-5-3 21:35:12 | 显示全部楼层
    扫描关注微中联,带你进入中联人的微世界
    是否应慎用规则引擎,像这种通用计算规则应该封装成公用逻辑块,毕竟规则引擎是开放给实施人员的,如果其他人改了,可能会影响程序的正常运行。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|管理细则|中联论坛 ( 渝ICP备12005023号  

    GMT+8, 2020-7-15 15:47 , Processed in 0.132664 second(s), 28 queries .

    Powered by Discuz! X3.2

    © 2020 ZLSOFT

    快速回复 返回顶部 返回列表