随着 IT 技术的普及和发展,用户的信息化水平越来越高,软件产品除了满足用户的基本需求之外,还必须越来越照顾到用户的个性化需求,为用户提供深层次的">个性化服务。以一个包含报表展示功能的产品为例,默认呈现给所有用户完全相同的报表,即同一个报表的字段内容和标签对所有用户完全相同。而在实际中,我们常常会遇到不同的用户由于其业务需求的不同,对于同一张报表,除基本数据字段之外,还要求额外增加符合该用户特定业务含义的字段,我们称之为用户自定义字段(Custom Metric)。这类需求在财务报表,数据分析报表中是比较常见。对于用户自定义字段,不同的用户给定不同的计算公式,甚至对于同一个用户的同一个字段,其计算公式也可能会随着时间推移而改变。一种直观的方法就是将所有用户有可能用到的字段都存储起来,然后再对不同的用户实现不同的字段,这样不仅会造成存储空间的浪费,而且后期的维护成本也十分高昂。本文将介绍一种基于 JEP 和可配置公式的解决方案,在不增加额外存储空间的情况下,灵活快速的解决用户的该类需求,并且具有良好的维护性和扩展性。
JEP 介绍
考虑到很多人对 JEP 还比较陌生,在介绍整个实现方案之前,有必要先让您对 JEP 有一个初步的了解。
JEP(Java Math Expression Parser)是一个第三方的 Java 工具包,提供了一套用于解析和计算数学表达式的类库,其核心功能就是计算公式的解析和结果的计算。在 JEP2.4.1 版本之前为符合 GPLv3 协议的开源免费包,你可以在 sourceforge 网站上下载和使用。使用 JEP 提供的 API,可以根据用户给定的公式来即时计算结果。JEP 支持用户自定义变量、常量和函数。在 JEP 中,已经预先包含大量的可使用的通用数学函数和常量,可满足日常的绝大部分数学计算需求。其官方网站是 http://www.singularsys.com/jep/,大家可以在该网站上下载试用版本和相关文档。
JEP 具有如下的特性:
文件小巧(jar archive 文件
大小在 300k 以下) 快速求值 精度高,计算中使用 BigDecimal 包含常见的数学函数和运算符 支持布尔型表达式 良好的可扩展和可配置性 支持字符串,向量和
复杂数值 支持隐式乘法 允许声明的或者未声明的变量 兼容 JAVA1.5 支持 Unicode 字符 大量的开发文档供参考 包含 JAVACC 语法分析生成器可自动生成 main class
JEP 对一个表达式的计算分为两个步骤。JEP 首先会对表达式进行解析,解析后会生成一个树形结构,接下来会基于这个树形结构进行快速求值。其工作流程图如下:
图 1. JEP 工作流程图
从上图可以看出,JEP 的工作过程十分简单。下面举一个简单的例子进行进一步说明,让您对 JEP 有一个更加直观的了解。
清单 1. JEP 简单示例 Jep jep = new Jep(); try { int x = 10; //1. 设置变量的值 jep.addVariable("x", x); //2. 载入并解析公式 jep.parse("x+1"); //3. 计算结果 Object result = jep.evaluate(); //4. 输出显示 System.out.println("x + 1 = " + result + " (When x="+x+")"); } catch (Exception e) { System.out.println("An error occured: " + e.getMessage()); } 输出结果:x + 1 = 11.0 (When x=10)
经过以上的介绍,想必您已经对 JEP 有一个初步的认识,那么接下来就可以开始进入本文的主题了。