根据DMN规范,B-FEEL(业务友好表现力表达式语言)是FEEL语言的一种方言。虽然两者共享相同的语法(Grammar),但在执行语义(Semantics)上存在显著差异,旨在使表达式对非IT用户更加直观。
以下是B-FEEL与FEEL之间具体差异的详细对比:
1.核心哲学与null值处理
语义定位:FEEL是一种严谨的表达式语言;而B-FEEL则通过修改语义,使其对业务人员更友好、更符合直觉。
null的含义:在FEEL中,null同时代表“数据缺失”或“执行错误”;在B-FEEL中,null仅用于表示数据缺失。
错误恢复:当发生错误时,FEEL通常返回null;而B-FEEL会将其语义修改为返回一个非空(non-null)的默认值。
2.逻辑运算差异(二值逻辑vs.三值逻辑)
逻辑系统:FEEL使用三值逻辑(true,false,null);B-FEEL将null从错误结果中移除,使其成为二值逻辑(仅true和false)。
不兼容类型比较:在B-FEEL中,对不兼容类型进行布尔运算(如="a"=1)始终返回true或false,而不会返回null。
l 大部分布尔操作在类型不兼容时返回false(例如<、<=、in、between等)。
l 特例:不等于操作!=在类型不兼容时返回true。
3.内置函数返回值的修改
当函数执行出错或参数无效时,两者的返回结果不同:
类别 | FEEL返回值(错误时) | B-FEEL默认返回值(错误时) | 示例(B-FEEL) |
数值函数 | null | 0 | decimal("a",0)返回0 |
字符串函数 | null | 空字符串("") | lowercase(12)返回"" |
布尔函数 | null | false | any(null)返回false |
日期与时间 | null | Unix纪元(1970-01-01) | date(null)返回1970-01-01 |
持续时间 | null | 0秒/0个月 | duration("a")返回P0M |
集合函数 | null | 空集合([]) | split("abc",22)返回[] |
范围函数 | null | 空范围((0..0)) | range("x")返回不匹配任何值的范围 |
4.列表处理逻辑
非数值过滤:在执行sum()、mean()、median()、stddev()等数值聚合函数时,B-FEEL会自动忽略列表中的非数值参数,而FEEL则可能因为包含非数值项或null而导致整个函数返回null。
l 示例:sum([1,"1",3])在B-FEEL中返回4。
5.算术运算的隐式转换
B-FEEL在类型不匹配时引入了更强大的隐式转换机制:
加法与减法:如果操作数之一是字符串,B-FEEL会将另一个操作数也转换为字符串进行拼接。
l 示例:"Todayis"+today()在FEEL中返回null,在B-FEEL中返回"Todayis2020-01-01"。
混合类型算术:在B-FEEL中,日期或时间与数值相加时,数值会被自动视为持续时间(取决于上下文)并参与运算。
乘法与除法:当操作数不匹配时,B-FEEL尝试将其转换为数值计算,若失败则返回0。
6.使用方式差异
URI标识:FEEL的默认URI为https://www.omg.org/spec/DMN/20240513/FEEL/。
B-FEEL启用:若要使用B-FEEL,必须将表达式语言明确设置为https://www.omg.org/spec/DMN/20240513/B-FEEL/。
总结:B-FEEL是FEEL的“宽容版”。它通过牺牲严谨的类型检查,换取了业务场景下的稳健性,确保决策流程不会因为单个数据的微小错误或缺失而彻底中断执行。