深度实现 - EL表达式解析引擎 + 通用逻辑组件:性能强、可处理各类表达式内置多种函数、对象且可扩展 - Tmm-EL

好长时间没写文章了,各位老铁 - 久等了,今天分享一个强大工具引擎,暂且叫它TMM-EL吧

本引擎为Java版本(后面考虑做其他语言版本),主要功能有:

  • 常用表达式解析:数学表达式(加减乘除模)、位表达式(与或非异或、左移、右移)、逻辑表达式、赋值表达式
  • 类注册器(注册后可以表达式中添加常用对象方法,如StringUtil,如别名为SU,表达式中可用SU.isEmpty....),类注册器可扩展
  • 函数注册器(与类注册器相似,注册函数):解析器内置常用函数库,如len/size/floor/substring等,函数可扩展
  • 常用类型转换:使用双冒号进行转换,如a::int,即将a强制转换为int类型,(1,2,3,4):: bytes将数组转换为字节数组
  • 常量可识别:数字(10进行、8进制、2进制和16进制)、静态字符串(''小引号)、动态字符串(``反引号内可使用${xxx}来动态引用上下文变量)
  • 括号嵌套无限制
  • 方法参数动态匹配
  • 背景:

在日常工作中,经常遇到某个平台或功能,需要进行多次迭代的场景,这些场景中绝大部分都是对之前功能的补充(换句话讲:核心逻辑还是之前版本,只是加入了用户需要的某个条件分支,输出为他们想要的结果),举个栗子:第一个版本的需求:当设备上报数据小于100时,将这个数据发布到MQ主题T1中,当大于100时,则发送数据到主题T2中。过了一段时间,用户有了新的需求,当大于500时,需要将数据发布 到MQ的T3主题上。。。(从迭代或运维的开发小伙伴,可能大部分都在做类似的工作)。

上面的例子只是冰山一脚,在“浩瀚”的工作任务中,这样类似的工作可能是某些同胞正在做、将一直需要完成的工作,且对用户端是无感的,这些逻辑不可视,不可配置。

常态可能是:反复修改源码,加入判断逻辑,自测、测试、上线部署。。。青春就是这么流逝的

为了能让身边的小伙伴快些完成工作,经过长时间的思考后,决定完成一个自研EL表达式解析器,并搭配其他组件一起赋能:快速何迭代,解耦并可以进行配置式热部署(上线)

public abstract class Function {
    protected boolean isOper;
    protected int args;
    public Function(int cnt){
        this.args = cnt;
        this.isOper = false;
    }

    public Function(int cnt, boolean isOper){
        this.args = cnt;
        this.isOper = isOper;
    }

    /**
     * 自定义方法执行入口
     * @param param
     * @return
     */
    public abstract Object execute(Object param);
}


RoundFunction roundFunction = new RoundFunction(1);
registerFunction("round", roundFunction);
FloorFunction floorFunction = new FloorFunction(1);
registerFunction("floor", floorFunction);
CeilFunction ceilFunction = new CeilFunction(1);
registerFunction("ceil", ceilFunction);
// 以上是内置函数,如果想扩展,继承抽象类Function即可

// 以上是内置函数,如果想扩展,继承抽象类Function即可

对象注册类似。。。

下面描述一下表达式引擎的实现过程:

表达式第一关:需要识别操作符,并明确操作符的操作数个数,实现过程添加一个大的操作符集合,对表达式进行遍历,并将遍历后的表达式压入堆栈

下一步进行运算:首先解析出操作数:定位操作符过程需要结合操作符的优先级,优先级高的先进行计算,相同优先级的操作符按从左到右的操作顺序进行运算,解决括号嵌套问题,及方法的引用 和参数个数匹配问题等

接下来为了满足不同业务需要,进行包装应用,因为在日常编码逻辑中,经常遇到条件判断,所以需要将表达式放到各种判断逻辑中,首先抽象出公用的解析包装组件,暂且叫他ElBlock

这个包装中应该满足:

  • 可以进行任意多的if-then-else以及嵌套
  • 加入final语义
  • 可以在上下文中使用赋值表达式,定义变量供后续使用
  • 表达式在项目启动后立即编译,真正调用时,直接使用ElBlock的eval功能(性能超强,一般场景基本上和调用Java字节码差不了多少)

包装的结构是这样的:(下图)

以上的解析组件,可用于各类业务场景中,如果可以这些属性,如def,condition/then,可以固化到DB中,结合实现业务包装一些功能开放给用户,这样就完成了上文中所说的:解耦、热部署了。。。。。。。。。。。。。。。。。

Over

以上就是个人针对通用逻辑进行的一些工作,零零碎碎花掉了大约1~2个月的时间,后续还会进行优化,欢迎有兴趣的小伙伴进行指定,如果对这个小东西兴趣可以发个人邮件babogd@163.com、微信:babogd或在下方进行评论讨论,加油~~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值