类别允许规则(资产)用你定义的任何数量的组别进行标记。这意味着你可以查看匹配某个类别的一个规则列表。规则可以属于任何数目的类别。在上面的图表里,你可以看到的是类似于文件夹/浏览器的资产视图。其名字是由
BRMS 管理员定义的(你也可以删除/添加新类别;但你只能在它们没有在使用时删除它们),可以是你希望的任意名称。
通常,类别是用匹配规则应用的商业领域的有意义的名称来创建的。(因此,如果规则应用在多个领域,你可以附加多个类别。)类别也可以用来标记规则为生命周期的某个阶段,例如标记为 "Draft“ 或 "For Review“。
上面的视图显示了你打开资产时看到的 Category Editor/Viewer。在这个例子里,你可以看到资产属于两个类别。这意味着当其中任何一个类别用于显示资产列表时,你都将看到该资产。(“+” 按钮和 Garbage Can 图标可分别用来添加和删除其他项目。)
在上面的例子里,第一个类别('Home")位于 "top level"。而第二个类别 “Mortage/Eligibility" 仍是一个单一的类别,但它是嵌套的,这是因为类别是具有层次结构的。要以另外一种方式表述它,就是名为 “Mortage" 的类别包含一个类别 “Eligibility“。屏幕将它显示为 ”Mortage/Eligibility”。如你所看到的,
当你打开一个资产以进行查看或编辑时,你会看到它所属的类别列表。如果你进行了修改(删除或添加类别),你将需要保存资产,且这个行为将在版本历史里创建一个新的条目。修改规则的类别不会影响其执行。
上面的视图显示了设立类别的管理屏幕。系统里缺省是没有类别的。因为类别是具有层次结构的,创建子类别时你必须选择“父”类别。在这里,你也可以删除类别(但只能在它们没有被任何资产使用的情况下)。
作为一个普通的规则,资产应该属于一个或两个类别。当你有大量的规则时,类别是很重要的。其层次结构不需要太深。红帽设计它们是为了帮助你将规则/资产分解为可管理的小片内容。
BRMS 平台支持几个资产(规则)格式。我们描述的是关键的格式。本手册里的其他部分将涵盖另外一些格式,其细节则不会在此重复。
资产编辑器里的可用选项取决于编辑的资产类型。资产编辑器用于编辑规则,它也可以用于添加、删除、出席排序条件、约束、行为、字段和选项。资产编辑器也允许用户使用工作集、检验和验证规则以及查看规则源。
相关的细节请查看资产编辑器里的工具提示。
当编辑规则时,资产编辑器也称为 ”Guided Editor“。
Guided Editor 用于编辑商业规则语言(
BRL)格式的规则。Guided Editor 提示用户根据正在编辑的规则的对象模型进行输入。
在你可以使用
BRL Guided Editor 之前,你必须先配置软件包访问。
Eclipse 插件里也包含一个 Guided Editor。本节里大部分细节也适用于它。
规则由多个部分组成:
When
Then
规则的
Then 部分是规则的条件部分已经满足后必须执行的行为。例如,在
例 4.1 “Guided Editor” 里,when 部分是:当申请者低于 21 岁。
使用 Guided Editor 也可以在 When(或条件)部分添加更多的条件并在 Then(或行为)部分添加更多的行为。例如,如果一个 21 岁以下的申请者有贷款申请的担保人,银行可能决定批准它的贷款申请。为了将这种情形在
例 4.1 “Guided Editor” 里模型化,修改何时包括担保人条件是有必要的。
要在条件里添加担保人,你首先需要在 Mortgage 模型的 Fact Type 里添加 guarantor 字段。
过程 4.1. 在 Fact Type 里添加字段
选择模型
从屏幕的左侧导航面板里选择 Knowledge Bases。扩展包含模型的软件包并选择 model。
点击 open 从列表里打开模型。
添加字段
点击后面的加号以扩展 Fact Type,然后选择添加字段(Add Field)。
输入字段细节
添加细节到弹出对话框里。在 Field name 字段里输入名称 guarantor,然后从 Type 下拉菜单里选择 True or False。
选择 File 和 Save changes 将修改保存到模型里。
因为在 applicant fact 类型里添加了 guarantor 字段,我们有可能修改规则以包括一个 guarantor。
过程 4.2. 在规则里添加限制
删除当前的限制
当编辑现有的规则时,你有必要删除当前的限制。这可以确保处理多个限制时选择正确的逻辑操作符(And 或 Or)。
在这个例子里,点击 Age 条件后面的减号。
修改约束
点击文本 There is an Applicant 打开 Modify Constraints Dialogue。
从 Add a restriction on a field 下列菜单里选择限制。在这个例子是选择 Age。
从 Multiple field constraints 下列菜单里选择 All of (and)。
指定第一个约束
点击文本 all of the following 以打开 Add fields to this constraint 对话框并添加限制。在这个例子里是选择 Age。
从新的下拉菜单里选择 less than,然后点击铅笔图标以编辑它的值,选择 literal,然后点击 Value 输入合适的值,这个例子里是输入 21。
指定第二个约束
点击文本 all of the following 以打开 Add fields to this constraint 对话框并添加限制。在这个例子里是选择 Guarantor。
从新的下拉菜单里选择 equal to,然后点击铅笔图标以编辑它的值,选择 literal,然后点击 true 输入合适的值,并选择 False。
你可以通过 Guided Editor 里的 Options 中编辑 Saliance。Salience 是一个代表优先级的数值。
请注意,你可以将字段值限制为预先配置的列表条目。这个列表配置为软件包(用于填充值的数据枚举)的一部分。这些值可以是固定列表,如从数据库里加载的值。对于具有给定值的代码和其他字段,这尤其有用。它也可以以下拉列表的方式显示在屏幕上,和规则里使用的值(或代码)不一样。关于如何进行配置,请参考 "Data Enumerations" 章节里的内容。
如果规则所属的软件包具有 DSL 配置,在你添加条件或行为时,它将提供一个 “DSL 语句” 列表,你可以从中选择(选择一个条目会添加一行规则),凭借来自用户的 DSL 指定值,编辑框(文本)将会显示(它组成一个表单)。请注意这是可选的,你可以选择其他 DSL 编辑器。
Guided Editor 目前不支持完整的 DSL 功能,它只支持 DSL 配置的 [when] 和 [then] 部分。
下面的图表显示了 Guided Editor 里的
DSL 语句:
DSL 规则是文本值,它使用一个语言配置资产来控制其外观。
DSL 是一个单一的规则。在上面的图片里,你可以看到文本编辑器。你可以使用右侧的图表来提供条件和行为列表以供选择(或者同时按住 Control 和空格键来弹出列表)。
多个规则可以存储在 Microsoft Excel 的电子表格里(.xls 文件格式),每一行都代表一个规则。本章不会涉及电子表格的细节。
要使用电子表格,如
图 4.7 “电子表格决策表” 所展示的,上传一个
.xls 文件。你也可以下载从相同的对话框下载当前版本的电子表格。为了创建一个新的决策表,你必须启动“规则向导“,它包含一个这个过程的选项,然后你可以上传
.xls 文件。
Guided 决策表功能允许决策表在 web 上编辑。它通过内省哪些 fact 和字段可用来引导决策表的创建,这和 Guided Editor 类似。规则属性、元数据、条件和行为都可以以治表格式定义,从而有助于大量相关规则的快速输入。象其他规则资产一样,基于 Web 的决策表会被编译成 DRL。
你可以多种方式选择单元格:
你可以双击单个的单元格以弹出对应底层数据类型的编辑器。相同列的单元格组可以通过点击第一个单元格并拖动光标或在点击第一个单元后再点击要选取范围里的最后一个(同时按住 Shift 键)来进行选择。
或者,你也可以使用箭头键在表格里移动。按住 Enter 键将弹出对应的编辑器。按住 Shift 同时用箭头键扩展选择范围可以选择一个区域。
如要修改列的大小,用鼠标在表头的分界处悬停,然后拖动鼠标光标将使列变窄或变宽。
Guided 决策表分成两个主要的部分:
列可以有下列的约束类型:
Literal
单元格里的值将用操作符和字段进行比较。
Formula
单元格里的表达式将被评估,然后和字段进行比较。
Predicate
不需要字段,表达式将被评估为 true 或 false。
你可以设置缺省值,但通常在单元格里没有值的话,约束不会被应用。
在缺省情况下,包含规则号码和描述的两列都会被提供。
你可以添加代表任何 DRL 规则属性到零或多个属性列。在 Guided 决策表编辑器来还有一个额外的伪属性来 "否定(negate)" 规则。使用这个属性可以否定整个规则。例如,下面的简单规则可以被否定。
when
$c : Cheese( name == "Cheddar" )
then
...
end
when
not Cheese( name == "Cheddar" )
then
...
end
你可以定义零个或多个元数据,每个都代表 DRL 规则上正常的元数据注解。
条件代表右手边定义的事实模式(fact pattern)或规则的 "When" 部分。要定义一个条件列,你必须定义模型类绑定或者选择一个已经定义的绑定。完成后你就可以定义字段约束了。如果两个或多个列都使用了相同的事实模式绑定,字段约束将变成相同模式的复合字段约束。如果你为单个的模型类定义了多个绑定,每个绑定都会变成规则右手边的单独的模型类。
你可以定义行为列来在规则引擎的工作内存里执行绑定事实上的简单操作或者创建全新的事实。新的事实可以在逻辑上插入到规则引擎的工作内存,从而服从平常的真相维护(truth maintenance )。关于真相维护和逻辑插入的更多信息,请参考《JBoss Rules 参考指南》。
本节允许使用之前定义的列来定义个体规则。
决策表左上角的图标切换单元格合并的开与关。当进行单元格合并时,那些在相同列里且具有相同值的单元格将合并成单个的单元格。这简化了修改分享相同原始值的多个单元格的内容。当单元格被合并时,它们也在单元格的左上角显示一个图标以允许对跨越合并单元格的行进行分组。
已经被合并的单元格可以进一步收缩成单一的行。点击左上角的 [+\-] 图标将收缩对应的行为一行。跨越收缩的具有相同值的行的其他列里的单元格将不受影响。而跨越收缩的具有不同值的行的其他列里的单元格将高亮显示且显示第一个值。
当分组单元格的值被改动时,已经收缩的所有的单元格都将更新它们的值。
定义为使用等号 == 或不等号 != 操作符的 literal 值的条件列可以利用一个特殊决策表的单元格值 otherwise。这个特殊的值允许定义规则来匹配没有在表里其他规则里显性定义的值。我们最好用以下的例子来解释:
when
Cheese( name not in ("Cheddar", "Edam", "Brie") )
...
then
...
end
when
Cheese( name in ("Cheddar", "Edam", "Brie") )
...
then
...
end
规则模板允许用户定义一个带有占位符(其值从表数据里获取)的规则结构。也你也可以继续使用 Literal 值、公式(Formula)和表达式(Expression)。
规则模板经常可用来替换决策表。
过程 4.3. 创建规则模板
创建规则模板资产
从 Knowledge Bases 菜单,选择 Create New,然后选择 New Rule Template。
定义资产
输入模板的名称、类别和描述。
定义模板
使用 guided editor 来构造规则。模板关键字(Template key) 是字段约束和行为部分里的占位符。你也可以在标准 guided editor 继续使用 Literal 值、公式(Formula)和表达式(Expression)。
例 4.3 “示例模板” 解释了一个已经用模板关键字(Template Key)定义的简单规则,它用于申请者的最大年龄、最小年龄和信用级别。模板关键字已经分别定义为 "$max_age"、"$min_age" 和 "$cr"。
当你完成规则模板的定义后,你需要输入用于插入“模板关键字”占位符的数据。BRMS 提供了在 Guided Editor 屏幕上的灵活的网格里输入数据的机制。在 Guided Editor 屏幕上按 Load Template Data 按钮可以启动网格编辑器。
规则模板的数据网格是非常灵活的,对于底层不同的数据类型有不同的弹出编辑器。列可以调整大小和排序,而单元格可以合并和分组以助于快速的数据录入。
每个Template Key 占位符可插入一行数据,由此每一行都称为了一条规则。
如果某一样的任何单元格为空,那么该行规则就不会生成。
网格左上角的图标切换单元格合并的开与关。当进行单元格合并时,那些在相同列里且具有相同值的单元格将合并成单个的单元格。这简化了修改分享相同原始值的多个单元格的内容。当单元格被合并时,它们也在单元格的左上角显示一个图标以允许对跨越合并单元格的行进行分组。
已经被合并的单元格可以进一步收缩成单一的行。点击左上角的 [+\-] 图标将收缩对应的行为一行。跨越收缩的具有相同值的行的其他列里的单元格将不受影响。而跨越收缩的具有不同值的行的其他列里的单元格将高亮显示且显示第一个值。
当分组单元格的值被改动时,已经收缩的所有的单元格都将更新它们的值。
规则作者可以查看将为规则模板和相关联的数据生成的 DRL,虽然这并没有必要。这个功能及其操作和用于其他资产的没有区别。选择 Source,然后再从资产编辑器屏幕选择 View Source 菜单。这将显示所有规则的 DRL。
规则流:规则流允许你用可视方式描述进行的步骤 - 所以不是所有的规则都会立即进行评估,这是一个逻辑流。本章不会涵盖 BRMS 上的规则流,但你可以使用 IDE 画出图形化规则流并上传 .rfm 到 BRMS。
和电子表格相似,你可以上传/下载规则流文件(Eclipse IDE 有个对应的图形化编辑器)。我们不会在此讨论规则流的细节。
技术性规则(
DRL)存储为文本且可以在
BRMS 里进行管理。
DRL 文件可以包含一个或多个规则。如果文件只包含一个规则,那么软件包、导入和规则语句都是不必要的。你可以只使用 "When" 和 "Then" 来分别标记 "Condition“ 和 "Action" 部分。
通常你将使用集成的开发环境来编辑 “原生”
DRL 文件,这是因为 IDE 拥有高级的工具、内容助手和调试功能。然而,有时候规则得处理 BRMS 里的软件包里的非常技术性的东西。在任何典型的规则软件包里,你通常都需要 “技术性规则”。当然你也可以将所有的规则类型混合并进行匹配。
功能是另外一类资产。它们不是资产且应该只在需要时才被使用。"Function Editor" 是一个文本编辑器。
数据枚举(Data enumeration)是资产的一个可选类型,你可以配置它为 Guided Editor 提供下拉列表。它们和其他资产一样可以存储和编辑,且只应用于它们所属的软件包。
枚举配置的内容是 "Fact.field" 到一个值列表的映射。这些值用在一个下列列表里。这个列表可以是文字的,或者使用工具类(你放入 classpath 里的)来加载字符串。这些字符串包含显示在下拉列表里的值,或者代码值(规则里使用的结尾)的映射和显示值(请看下面的例子,它使用 '=')。
'Board.type' : [ 'Short', 'Long', 'M=Mini', 'Boogie']
'Person.age' : [ '20', '25', '30', '35' ]
在上面的枚举配置里,"M" 表示用在规则里的值,而 "Mini" 则是显示在图形界面里的值。
从外部源获取数据列表
BRMS 也可以调用加载字符串列表的代码。为此,你需要一段返回
java.util.List 到
BRMS 的 classpath 的代码。不是指定
BRMS 的值列表,代码是返回字符串列表。(通常,如果你想为规则使用不同的显示值,你可以在字符串里使用 "=" 符号。)例如,你可以修改上面的
Person.age 行为:
'Person.age' : (new com.yourco.DataHelper()).getListOfAges()
这假设你有一个名为
DataHelper 的类,它有一个返回字符串列表(位于 classpath 上)的方法
getListOfAges()。你当然可以将这些 “动态的“ 枚举和固定列表混合。例如,你可以用
JDBC 从数据库里加载它们。你第一次在会话里使用 Guided Editor 时将加载数据枚举。如果你有任何打开的 Guided Editor 会话,你将需要关闭它并重新打开规则才能看到发生的变化。要检查枚举是否已经加载,请进入软件包配置屏幕。你可以使用"保存并检验(save and validate)"软件包,这可以检查并反馈任何发生的错误。
对于数据枚举,你还可以执行一些其他的高级任务。
取决于字段值的下拉列表
假设有一个简单的事实模型,你有一个名为 Vehicle 的类,它有两个字段组成:"
engineType" 和 "
fuelType"。对于 "
engineType" 你希望选择 "
Petrol" 或 "
Diesel"。现在,很明显燃油的选择必须取决于引擎类型(对于汽油我们有
ULP 和
PULP,而对于柴油我们有
BIO and
NORMAL)。我们可以在枚举表达式里表达这种依赖关系:
'Vehicle.engineType' : ['Petrol', 'Diesel']
'Vehicle.fuelType[engineType=Petrol]' : ['ULP', 'PULP' ]
'Vehicle.fuelType[engineType=Diesel]' : ['BIO', 'NORMAL' ]
这显示了如何通过根据其他字段的值来进行选择。请注意,一旦你选择了 engineType,fuelType 的选项列表就被决定里。
在程序里加载枚举
在某些情况下,我们胡会希望从外部数据源(如关系型数据库)加载自己的枚举数据。为此,你可以实现一个返回 Map 类型的类。这个 Map 的键是一个字符串(就是上面显示的 Fact.field 名称)。它的值是一个字符串的 java.util.List。
public class SampleDataSource2 {
public Map<String>, List<String>> loadData() {
Map data = new HashMap();
List d = new ArrayList();
d.add("value1");
d.add("value2");
data.put("Fact.field", d);
return data;
}
}
在 BRMS 的枚举里,输入下列内容:
=(new SampleDataSource2()).loadData()
"=" 符号表示通过执行你的代码加载数据。
更多高级的枚举
在上面的例子里,列表里的值会“先”被计算。对于相对静态或小型数据来说,这是非常足够的。然而,假设我们有一个国家列表,而每个国家都有一个州的列表,而每个州又有自己的地区列表,地区则有街道列表等等。此时你就会发现这需要大量的数据,这么大的数据是无法被一次加载的。所以,可以根据所选的国家来加载列表。
这种情况可以下列方式解决:
'Fact.field[dependentField1, dependentField2]' : '(new com.yourco.DataHelper()).getListOfAges("@{dependentField1}", "@{dependentField2}")'
请注意,只有需要的字段才被指定。而且,在右边的 ":" 符号中,表达式是用引号括起的。这个表达式只在需要时才会被估值。此时,它将替代指定的字段的值。这意味着你可以使用图形化用户界面的字段值来驱动数据库查询,然后再向下查询数据,诸如此类。当加载了规则的下拉列表后,列表将根据这些字段进行刷新。"
depenentField1" 和 "
dependentField2" 是 "Fact" 类型上的字段名称。它们用于计算作为 ”字段“ 值显示在下拉列表里的值列表。
BRMS 里的每个资产和软件包都有一套
状态标记(status flag)。这些标记的值可以在
BRMS 的“管理”章节找到。在这里,你可以添加自己的状态名称。和类别相似,状态也不会以任何方式影响执行。它们只是提供信息而已。
不像类别,资产在某个时刻只有一个状态。
状态的使用完全是可选的。你可以采用它们或类别来管理资产的生命周期。
上面的图表描述单个资产的状态变化。这种变化会立即发生;它不需要单独地保存。
你也可以修改整个软件包的状态。这会设置软件包自身和属于它的所有资产的状态标记为同一个值。
在
BRMS 里,你有一个"
知识库(Knowledge Base)",它包含一个或多个"
知识软件包(Knowledge Package)"。在用户界面里,知识软件包通常被简单地称为 "
软件包."。
配置知识软件包通常只进行一次,它应该由具有开发规则和模型经验的人员来完成。很少有人需要配置知识软件包,只要配置完毕,它可以按需要多次进行复制。软件包配置肯定是一个需要规则开发经验的技术性任务。
所有的资产都位于
BRMS 的“软件包”里。软件包就像一个子目录(它也可作为“命名空间”)。它和规则资产所在的主目录等同。特别是规则需要知道 fact model 和命名空间的性质。
上面的图片展示了软件包浏览器(Package Explorer)。点击资产类型将显示对应的一个列表(对于具有数千个规则的软件包,这需要几秒钟才会显示出来,因此使用类别来加速浏览很重要)。
总而言之,虽然规则(资产)可以出现多个类别里,它们只位于一个软件包内。如果你将
BRMS 当作一个文件系统,则每个软件包都是一个目录,而其中的资产就是文件列表。
软件包管理功能允许你查看知识软件包列表并“扩展”为每个“类型”的小型列表(资产可能很多,所以其中一些进行了分组):
你可以使用软件包浏览器(Package Explorer)创建新的规则或资产。有些资产只能通过软件包浏览器创建。
图 4.22 “创建新的资产” 展示了启动该功能的“向导”的图标。
你需要做的最重要的事情是配置软件包。这个任务涉及导入规则使用的类并定义全局变量两个方面。进行了修改后,你需要保存它。此时,软件包就已经完成配置并准备好进行构建了。例如,你可以添加一个具有类 com.something.Hello 的模型。然后你将在软件包配置里添加 import com.something.Hello 并保存修改。
在导入软件包的类并定义了全局变量后,你可以构建软件包。软件包包含的资产越多,构建需要的时间越长。构建成功后,你将可以为部署创建一个“快照”。此时,你也可以查看软件包构建时生成的“
drl”。
你也可以通过导入现有的 "
drl" 文件来创建软件包。当你选择创建新的软件包时,你可以选择上载一个
.drl 文件。
BRMS 将试图解析这个
drl 并自动创建一个软件包。它里面的规则将作为单个资产保存(仍然是
drl 的文本内容)。请注意,要实际上构建软件包,你需要上载一个合适的模型(以
.jar 形式)以供检验。这是一个单独的步骤。
在
BRMS 里,整个知识软件包和单个资产都带
版本,单每个的机制都不太一样。单个资产在源码控制系统(
Subversion)里以文件版本的形式保存。然而,资产软件包通过快照方式根据需要(“On Demand”)划分版本。这个快照用于部署。下一节我们讨论部署管理和快照的更多细节。
每次对资产进行修改后,它都在版本历史记录创建一个新的条目。这为你提供了无限制的“Undo”功能。你可以查看单个资产的历史(如上面的列表所示),然后按照时间进行恢复。
URL 是围绕如何提供构建的知识软件包的过程的中心。BRMS 通过 URL 提供知识软件包以供知识代理(Knowledge Agent)下载和使用。这些 URL 采用这种格式:http://localhost:8080/jboss-brms/org.drools.guvnor.Guvnor/package/<packageName>/<packageVersion>
<packageName> 是你给软件包取的名字。<packageVersion> 是快照的名称或 "LATEST"(如果它是“LATEST”,那么它将是从主软件包里构建的最新版本而非快照)。你可以在代理里使用它或者将其粘贴到浏览器地址栏里作为文件下载。
上面的映像展示了
Deployment Snapshots 视图。左侧有一个知识软件包列表。点击某个软件包,它将为你展示它的所有快照(如果有的话)。你可以复制、删除或查看快照。每个快照都可以下载或通过
URL 访问。下载后你就可以部署它。
查看库的两个主要途径是使用用户驱动的类别(也称为 tagging)和软件包浏览器(Package Explorer)视图。
分类视图(Category View)为你提供了浏览与你的机构相关的规则的途径。
上面的图表显示了分类功能。如果可能的话,将每个类别里的规则限制在几十个以下。
其他的视图使用软件包浏览器(Package Explorer)。这个视图以反映数据库里实际存储情况的方式显示资产。它也按照类型或格式将规则分开到知识软件包里。