camunda-dmn

       决策模型和标记DMN(Decision Model and Notation),是一个商业决策管理标准。
       当前camunda的DMN引擎部分支持DMN1.3标准,包括决策表(Decision Tables),决策字面量表达式(Decision Literal Expressions),决策需求图(Decision Requirements Graphs)和足够友好表达语言FEEL(Friendly Enough Expression Language )

决策表(Decision Table):将决策逻辑指定为表
决策字面量表达式(Decision Literal Expression):将决策逻辑指定为表达式
决策需求图(Decision Requirements Graph):为相互依赖的决策建模
足够友好表达语言FEEL(Friendly Enough Expression Language):DMN的默认表达式语言

一、DMN决策表(DMN Decision Table):

       决策表表示一个在DMN1.3中能够被描述成一个表格的决策逻辑。它包含输入(inputs),输出(outputs)和规则(rules)
       决策表在xml中用一个decision元素中的decisionTable元素表示:


  
    
    
    
  

图1:决策表

       决策名称描述了这个决策表提供的决策逻辑。它被设置成一个name属性在decision元素上。


  
  
  

1.决策表名称和编号(Decision Name / Decision Id):

       决策表名称(Decision Table Name)描述了这个决策表提供的决策逻辑。它被设置成一个name属性在decision元素上。


  
  
  

       决策表编号(Decision Id)是技术上的标识。它设置在decision元素的id属性上。每个决策必须要有唯一的id,当在部署到camunda BPM平台上时。引擎会将id用作部署决策定义的决策key。


  
  
  

图2:决策名称和编号
2.DMN决策表输入(DMN Decision Table Input):

       一个决策表有一个或者多个输入,也被叫做输入子句。输入子句定义了编号(id),标签(label),表达式(expression),决策表输入类型(type)

       一个input可以通过双击决策表各列的列头来进行编辑。

       在xml中输入子句用decisionTable内的input元素表示:


  
    
      
        
          season
        
      
      
    
  

图3:决策表输入
2.1.输入编号(Input Id):

输入编号是决策表input的唯一标识。

2.2.输入标签(Input Label):

输入标签是input的一个简短的描述。

2.3.输入表达式(Input Expression):

输入表达式指定输入子句的值如何生成。这是一个会被DMN引擎解析的表达式。它通常很简单并且引用一个执行期可见的变量引用。

2.4.输入类型定义(Input Type Definition):

当输入表达式被DMN引擎解析后,结果会被转换成指定的类型,支持的类型在用户指南中查看。注意:类型不是必须的,但是推荐要设置,因为它可以帮助我们明白可能的输入值,和提供类型安全的校验。

2.5.输入表达式语言(Input Expression Language):

表达式语言可以指定,输入表达式的语言,如果没有指定,则会使用definitions元素中的全局表达式语言。如果全局表达式语言也没有设置,则默认使用JUEL表达式语言。

2.6.输入变量名称(Input Variable Name):

当输入表达式被解析并返回解析的值时,值会被存储到一个变量中,这个变量的名称就是输入变量名称。这个变量名还能使用表达式。

3.决策表输出(DMN Decision Table Output):

       决策表可以有一个或者多个输出(outputs),也被叫做输出子句。输出子句定义了编号(id),标签(label),名称(name),决策表输出类型(type)。

       在xml中输入子句用decisionTable内的output元素表示。


  
    
      
      
      
    
  

图4:决策表输出
3.1.输出编号(Output Id):

输出编号是决策表输出的唯一编号,被camunda平台用来关联被执行的决策的历史输出。

3.2.输出标签(Output Label):

输出标签时一个输出的简短描述。输出标签不是必须的,但是推荐设置,因为他可以帮助我们理解决策。

3.3.输出名称(Output Name):

输出名称引用的是决策表执行结果的输出值。如果决策表有多个输出,那么所有的输出必须由唯一的名字。

3.4.输出类型定义(Output Type Definition):

当输出条目被DMN引擎执行后,将执行的结果转换成这个指定的类型。支持的类型见用户指南.类型不是必须的,但是推荐设置,因为它可以提供一个类型安全的输出值。
另外,这个类型可以用来将输出值转换成另外一个类型,例如将字符串类型的80%转换成浮点数,详细见用户定制数据类型

图5:决策表规则

4.决策表规则(DMN Decision Table Output):

       决策表可以有多个规则。每个规则包含多个输入和输出条目。输入条目是条件,输出条目是规则的结果。如果每一个输入条目都满足,那么这个规则就是满足的,那么决策结果就包含这个规则的输出结果
       在xml中,用decisionTable元素内的rule元素来表示一个规则:



  
    
      
      
        
          "Winter"
        
        
          
        
        
          "Roastbeef"
        
      
      
    
  

4.1输入条目(条件)(Input Entry (Condition)):

一个规则可以有一个个或者多个输入条目,这个条目就是这个规则的条件。每一个输入条目在text元素中包含一个表达式,如果这个输入条目满足,则表达式会被解析成true。


  "Spring"

4.2空输入条目(Empty Input Entry):

如果某个输入条目对这个规则无关紧要,这个表达式是空的,那么这个表达式一直都是满足的,即被解析为true。


  

如果使用的是FEEL表达式语言,那么空输入条目用-表示,其他的表达式是空。

4.3输入条目的表达式语言(Expression Language of an Input Entry):

表达式语言可以用expressionLanguage属性指定。支持的表达式语言见用户指南,如果没有设置表达式语言,就会使用设置在definitions中的全局表达式语言。如果全局表达式语言也没有设置,则会使用默认的FEEL表达式语言。

4.4输出条目(结果)(Output Entry (Conclusion)):

一个规则可以有多个输出条目,这个条目是规则的结果。每一个输出条目的text元素中包含一个表达式。


  "Steak"

4.5空输出条目(Empty Output Entry):

如果输出条目是空,那么输出会被忽略,并且不是决策表结果的一部分

4.6输出条目表达式(Expression Language of an Output Entry):

见输入条目表达式

4.7描述(Description):

见输出条目描述

5.DMN命中策略(DMN Hit Policy):

       决策表的命中策略指定决策表的结果由哪些组成。
       命中策略设置在decisionTable元素的hitPolicy属性中。如果没有设置,则默认是UNIQUE命中策略。


  
    
      
    
  

5.1命中策略的角色(The Role of a Hit Policy):

命中策略指定决策表的多少个规则可以满足,和哪些满足的规则会被包含到决策表结果中。unique, any 和 first命中策略总是会返回一个最满足的一个规则。rule order 和 collect命中策略会返回多个满足的规则。

5.2唯一命中策略(Unique Hit Policy):

只有一个或者没有规则可以满足。决策表的结果包含满足规则的输出条目。

如果超过一个规则满足,那么就违反了唯一命中策略。

5.3任何一个命中策略(Any Hit Policy):

多个规则可以满足,然后所有满足的规则都必须有相同的输出。这个决策表的结果只会包含一个满足规则的输出。

如果多个规则满足,并且生成了不同的输出,这就违反了命中策略。


图6:请假决策

这是一个请假的决策表。如果申请这没有假期,或者申请者正在试用期,申请会被拒绝。否则申请通过。

5.4第一个命中策略(First Hit Policy):

多个规则可以满足。决策表结果只包含第一个满足规则的输出。


图7:广告决策

参见上面的广告决策表。关于根据用户的当前年纪决定哪个广告应该被展示。例如,用户当前是19岁。所有的结果都匹配,但是因为这个命中策略是第一个命中策略,所以Cars广告将会被展示。

5.5规则顺序命中策略(Rule Order Hit Policy):

多个规则可以满足。决策表包含所有满足规则的输出,且按照规则在决策表中的顺序排序。


图8:广告决策

再看上面关于广告的决策,假设我们有一19岁的用户。所有的规则都满足,所以所有的输出都会按照规则的顺序给到决策表结果。它可能可以用来指示所显示广告的优先级。

5.6集合命中策略(Collect Hit Policy):

多个结果满足。决策表以任意顺序包含所有满足条件的输出结果。


图9:广告决策

这个命中策略,输出列表是没有顺序的。所以广告可以是任意的,如果年纪是19岁。

另外,集合命中策略可以指定一个聚合器(aggregator)。如果指定了聚合器,决策表的结果只会包含一个输出条目。聚合器会从所有的满足规则的输入条目生成这个输出条目。注意,集合命中策略使用了聚合器,决策表只能有一个输出。

5.7集合命中策略的聚合器(Aggregators for Collect Hit Policy):

集合命中策略还可以指定一个聚合器:
       Collect(Sum):所有输出值的求和
       Collect(Min):所有输出值中,最小的一个
       Collect(Max):所有输出值中,最大的一个
       Collect(Count):输出值的个数的统计

5.8求和聚合器(SUM aggregator):

求和聚合器将所有满足的规则的输出求和


图10:薪水决策

这个展示的决策表可以用作对一个员工的奖金进行求和,例如这个员工已经在公司工作了3.5年了。所以会满足第一、二、三个规则,并且这个决策表的结果就是600,所有的输出的求和。

5.9最小值聚合器(MIN aggregator):

最小值聚合器可以用作返回所有满足规则的最小输出值。看下图的汽车保险的例子。一个汽车多年没有发生事故,保险费用应该减少。


图11:汽车保险决策

例如,如果输入值是3.5年,那么结果应该是98.83,尽管第一、二、三个规则都匹配,但是第三个规则有最小的输出值。

5.10最大值聚合器(MAX aggregator):

最大值聚合器可以被用作返回所有满足规则的最大的输出值。


图12:零花钱决策

这个决策表表示小孩子的零花钱的数量的决策。根据小孩子的年纪增加,零花钱的数量会增加。例如,输入一个9,第一、二个规则会匹配到,第二个规则的输出比第一个规则的输出大,所以这个决策的输出是5.一个9岁的小孩子会得到5块钱的零花钱。

5.11计数聚合器(COUNT aggregator):

计数聚合器会返回满足的条件的个数


图13:薪水决策

例如,上图的奖金决策表,如果使用的是计数聚合器,且输入值是4,第一、二、三个规则满足,所以,这个决策表的结果是3,也就是说4年后决策表的结果是3个工资奖金。

二、DMN决策文字表达式(DMN Decision Literal Expression):

图14:决策字面量表达式

一个决策文字表达式表示决策逻辑可以被描述成一个DMN1.3的表达式。它由一个文字表达式和一个变量组成

在xml中,一个决策文字表达式可以用decision元素内的literalExpression元素表示:


  
    
    
      calendar.getSeason(date)
    
  

1.1决策名称和决策编号(Decision Name / Decision Id):
图15:决策文字表达式名称和编号

名称描述了这个文字表达提供的决策逻辑。它设置在decision元素的name属性中:


    

这个编号是决策的技术编号,它设置在decision元素的id属性中。
在部署到camunda BPM平台时,每一个决策应该有单独的编号。在部署决策定义时,这个编号被引擎用作决策的key


    

1.2文字表达式(Literal Expression):

这个文字表达式指定了决策的值是如何生成的。这是一个会被DMN引擎执行的表达式。它可以被用作复杂的计算,去调用一个提供了决策逻辑的bean,或者组合输出需求决策的值

表达式被设置在xml中literalExpression元素内的text元素中。


  calendar.getSeason(date)

1.3文字表达式语言(Literal Expression Language):

可以通过literalExpression的expressionLanguage属性指定文字表达式的表达式语言。支持的表达式语言详见用户指南


  calendar.getSeason(date)

如果没有设置表达式语言,会使用设置在definitions元素上的全局表达式语言。


  

如果全局表达式语言也没有设置,会使用默认的表达式语言JUEL,JUEL详见用户指南

1.4变量(Variable):

一个文字表达式必须由一个变量(variable),且指定了name属性和type属性作为决策的结果。变量声明在decision元素内的variable元素中。


  

1.5变量名称(Variable Name):

变量名称用来引用一个文字表达式的决策结果。它在xml中用name属性指定:


1.6变量类型定义(Variable Type Definition):

在variable元素中,决策结果的类型可以用typeRef属性指定。在决策表达式被执行后,会转换结果成指定的类型。支持的类型详见用户指南


注意,类型不是强制要求的,但是推荐提供。应该类型可以提供类型安全的表达式结果。

三、决策需求图(Decision Requirements Graph):

决策需求图(DRG)为决策领域建模,展示相关的最重要的元素和它们的依赖关系。建模的元素是决策(decisions),输入数据(input data),和知识源(knowledge sources)。

DRG的可视化表示称为决策需求图(DRD)。


图16:决策需要图

在XML中,DRG由definitions元素表示。


  
    
  
  
    
  

1.1决策(Decision):

一个决策需求图可以有一个或者多个决策。决策有名字和编号。决策逻辑必须在决策表中或者决策表达式中。

决策在definitions元素中的decision元素表示:


  
    
    
    
  

1.2被依赖的决策(Required Decisions):

一个决策可以有一个或者多个它依赖的决策,例如上图饮料的决策依赖食物的决策

一个必要的决策由informationRequirement元素内的requiredDecision元素表示。它有一个href属性和一个以#开始的值,这个值是必要的决策的编号(依赖的决策的id)。


  
      
  
  

1.3输入数据(Input Data):

输入数据表示一个或者多个决策的输入信息。

注意:输入数据没有执行的语义,并且会被camunda DMN引擎忽略。

它用definitions元素内的inputData元素表示:


  
  
  
    
      
    
    

1.4知识源(Knowledge Source):

知识源表示决策的权限。
注意:知识源没有执行的语义,并且会被camunda DMN引擎忽略。

它用definitions元素内的knowledgeSource元素表示:


  
  
  
    
      
    
    

三、足够友好的表达式语言(Friendly Enough Expression Language (FEEL)):

DMN提供了足够友好的表达式语言,它可以被用作执行决策表里的表达式

1.1 FEEL提供的数据类型(FEEL Data Types):

1.String:
       FEEL支持字符串,字符串必须被双引号包裹起来。字符串只支持equal比较操作
2.Numeric Types:
       FEEL支持数字类型,例如整数integer。在Camunda DMN引擎中可用的数字类型:
       integer
       long
       double
数字类型支持所有的比较操作和范围操作
3.Boolean:
       FEEL支持布尔值true和false。布尔值只支持equal比较操作
4.Date:
       FEEL支持时间类型。Camunda DMN引擎中执行以下类型的时间:
date and time
       要创建日期和时间值,必须将函数日期和时间与单个String参数一起使用。 该参数以yyyy-MM-dd'T'HH:mm:ss格式指定日期和时间。
Date支持所有的比较操作和范围

1.2 FEEL的语言元素(FEEL Language Elements):

Camunda DMN引擎支持FEEL输入条目。 输入条目中表达的FEEL术语是简单的一元测试。 这些简单的一元测试针对表达式测试输入值,如果满足测试,则返回true,否则返回false。 该表达式可以包含本节中描述的不同元素。

比较(Comparison):
FEEL的简单一元测试支持下面的比较操作。请注意,equals操作是空不是用=。另外,不等于操作不是!=,不等于操作要用逻辑非元素(negation)。

名称 操作 例子 描述
等于 "Steak" 测试输入值是否等于给定的值
小于 < <10 测试输入值是否小于给定的值
小于或等于 <= <=10 测试输入值是否小于等于给定的值
大于 > >10 测试输入值是否大于给定的值
大于或等于 >= >=10 测试输入值是否大于等于给定的值

范围(Range):
某些FEEL数据类型,例如数字和日期类型,可以测试是给定值是否属于某个范围。这个范围包括一个开始值和一个结束值。 还需指定开始和结束值是否包含在范围内。

开始 结束 例子 描述
包含 包含 [1..10] 测试输入值是否大于等于开始值并且小于等于结束值
不包含 包含 ]1..10] 或者 (1..10] 测试输入值是否大于开始值并且小于等于结束值
包含 不包含 [1..10[ 或者 [1..10) 测试输入值是否大于等于开始值并且小于结束值
不包含 不包含 ]1..10[ 或者 (1..10) 测试输入值是否大于开始值并且小于结束值

析取(Disjunction):
FEEL简单一元测试可以指定一个联合表达式。这个联合表达式可以是比较和范围。当至少一个表达式是true,测试的结果就是true。

例子:

  • 3,5,7:      测试输入值是否是3, 5或者7
  • <2,>10:        测试输入值是否小于2或者大于10
  • 10,[20..30]:       测试输入值是否是10,或者大于等于20且小于等于30
  • "Spareribs","Steak","Stew":        测试输入值是否是Spareribs, Steak或者Stew
  • date and time("2015-11-30T12:00:00"),date and time("2015-12-01T12:00:00"):        2015年11月30号12:00:00,或者2015年12月12:00:00
  • >customer.age,>21:       测试输入值是否大于变量customer的age或者大于21

逻辑非(Negation):
FEEL简单的一元测试可以与not函数否定。 这意味着,如果包含的表达式返回true,则测试将返回false。 请注意,仅允许一个否定运算符作为第一运算符,它可以包含一个析取运算符。

例子:

  • not("Steak"):        测试输入值是否不是Steak
  • not(>10):       测试输入值是否不大于10,这意味着输入值是小于等于10的
  • not(3,5,7):       测试输入值是否不是3, 5或者7
  • not([20..30]):       测试输入值是否不是大于等于20且小于等于30

指定名称(Qualified Names):
FEEL简单一元表达式测试可以通过指定名称访问变量和对象的属性

例子:

  • x: 测试输入值是否等于变量x的值
  • >= x: 测试输入值是否大于等于变量x的值
  • < customer.age: 测试输入值是否小于customer对象age属性的值

日期函数(Date Functions):
FEEL简单一元测试提供了函数去创建时间类型值。Camunda DMN引擎支持以下日期函数:

  • date and time("..."): 用字符格式yyyy-MM-dd'T'HH:mm:ss值创建一个时期时间值

例子:

  • date and time("2015-11-30T12:00:00"):        测试输入值是否是2015-11-30 12:00:00
  • [date and time("2015-11-30T12:00:00")..date and time("2015-12-01T12:00:00")]:        测试输入值是否在2015-11-30 12:00:00和2015-12-01 12:00:00之间

你可能感兴趣的:(camunda-dmn)