21.6. pet Store 示例决策(示例组、全局变量、回调和 GUI 集成)
Pet Store 示例决策集演示了如何在规则中使用平板组和全局变量,以及如何将红帽决策管理器规则与图形用户界面(GUI)集成,在这种情况下,基于 Swing 的桌面应用程序。这个示例还演示了如何使用回调与正在运行的决策引擎交互,以在运行时根据工作内存中的更改更新 GUI。
以下是 Pet Store 示例的概述:
-
名称 :
petstore
-
主类 :
org.drools.examples.petstore.PetStoreExample
(在src/main/java
中) -
模块 :
drools-examples
- 键入: Java 应用程序
-
规则文件 :
org.drools.examples.petstore.PetStore.drl
(src/main/resources
) - 目标 :演示规则索引组、全局变量、回调和 GUI 集成
在 Pet Store 示例中,示例 PetStoreExample.java
类定义了以下主体类(除了多个类来处理 Swing 事件外):
-
Petstore
包含main()
方法。 -
PetStoreUI
负责创建和显示基于 Swing 的 GUI。此类包含多个较小的类,主要用于响应各种 GUI 事件,比如鼠标点击的用户。 -
TableModel
包含表数据。这个类本质上是扩展 Swing 类AbstractTableModel
的 JavaBean。 -
CheckoutCallback
允许 GUI 与规则交互。 -
Ordershow
保留您要购买的项目。 -
购买
存储订购详情以及您要购买的产品。 -
产品是
JavaBean,其中包含可供购买的产品及其价格的详细信息。
本例中的大部分 Java 代码是基于普通 JavaBean 或 Swing。有关 Swing 组件的更多信息,请参阅有关 使用 JFC/Swing 创建 GUI 的 Java 教程。
Pet Store 示例中的规则执行行为
与其他示例决定设置被断言并立即触发,Pet Store 示例不会执行规则,直到根据用户交互收集更多事实。这个示例通过构造器创建的 PetStoreUI
对象来执行规则,接受 Vector
对象 库存
来收集该产品。然后,示例使用 Checkout Callback 类的实例
,其中包含之前载入的规则基础。
pet Store KIE 容器和事实执行设置
触发规则的 Java 代码位于 CheckoutCallBack.checkout()
方法中。当用户在 UI 中点击 Checkout 时触发 此方法。
来自 CheckoutCallBack.checkout()的规则执行
示例代码将两个元素传递给 CheckoutCallBack.checkout()
方法。一个元素是处理 JFrame
Swing 组件,位于 GUI 的底部。第二个元素是顺序项目的列表,它来自 GUI 右上角的表格区域的信息。
for
循环将来自于 GUI 的订购项列表转换为 Order
JavaBean,同时包含在文件 PetStoreExample.java
中。
在这种情况下,规则会在无状态 KIE 会话中触发,因为所有数据都存储在 Swing 组件中,并在用户点击 UI 中的 Checkout 之前执行。每次用户点击 Checkout 时,列表的内容都会从 Swing TableModel
移到 KIE 会话工作内存中,然后使用 ksession.fireAllRules()
方法执行。
在此代码中,对 KieSession
有 9 个调用。其中之一从 KieContainer 创建新的 KieSession
(在这个
中通过的示例从 KieContainer
main()
方法中的 CheckoutCallBack
类传递)。接下来的两个调用通过规则中存放全局变量的两个对象: Swing 文本区域以及用于编写消息的 Swing 帧。并将有关产品的信息插入 KieSession
以及顺序列表中的更多信息。最终的调用是标准 fireAllRules()
。
pet Store 规则文件导入、全局变量和 Java 功能
PetStore.drl
文件包含标准软件包和导入语句,以使规则可以使用各种 Java 类。规则文件还包括用于在规则(定义为 帧
和 textArea
)中使用的 全局变量。全局变量包含对之前由称为 setGlobal()
方法的 Java 代码传递的 Swing 组件 JFrame
和 JTextArea
组件的引用。与规则中的标准变量不同,在规则触发后,全局变量会保留其在 KIE 会话生命周期中的值。这意味着这些全局变量的内容可以对所有后续规则进行评估。
PetStore.drl 软件包、导入和全局变量
PetStore.drl
文件还包含两个使用中的规则:
PetStore.drl Java 功能
这两个功能执行以下操作:
-
doCheckout()
显示一个对话框,它要求用户是否被委派或需要签出。如果用户确实如此,则重点设置为结账
员组,使该组中的规则启用(可能)触发。 -
requireTank()
会显示一个对话框,该对话框要求用户如果她或想要购买财务语。如果用户确实有,则会在工作内存中的订购列表中添加一个新芬兰的 tank产品
。
在本例中,所有规则和功能都位于同一个规则文件中,以提高效率。在生产环境中,您通常将不同文件中的规则和功能分开,或构建静态 Java 方法并使用导入功能导入文件,如 导入功能 my.package.name.hello
。
pet Store 规则与日程组
Pet Store 示例中的大多数规则使用 table 组来控制规则执行。日程表组允许您对决策引擎日程表进行分区,以便对规则组提供更多执行控制。默认情况下,所有规则均位于 MAIN
日程小组。您可以使用 schedule -group
属性来指定该规则的不同日程表组。
最初,工作内存专注于 MAIN
的日程安排。仅当该组收到相关事项时,即可参与日程表组中的规则。您可以使用方法 setFocus()
或 rule 属性 auto-focus
来设置焦点。auto-focus
属性允许当规则匹配和激活时,自动为课程安排人员自动给定规则。
Pet Store 示例对规则使用以下日程组:
-
"init"
-
"评估"
-
"显示项目"
-
"checkout"
例如,示例规则 "Explode Cart"
使用 "init"
资格将 cart 项目触发并插入到 KIE 会话工作内存中:
规则"Explode Cart"
该规则与所有尚未计算的订单匹配。每个购买项目的执行循环按该顺序排列。
该规则使用与其 schedule 组相关的以下功能:
-
日程表组"init"
定义日程表组的名称。在这种情况下,组中只有一个规则。但是,Java 代码和规则都无法专注于此组,因此它也取决于其触发的机会的auto-focus
属性。 -
auto-focus true
可确保此规则,而作为 schedule group 中的唯一规则,但从 Java 代码调用fireAllRules()
时有机会触发。 -
kcontext….setFocus()
将焦点设置为"show items"
和"evaluate"
日程表组,支持他们触发的规则。在实践中,您要循环顺序的所有项目,将它们插入到内存中,然后在各个插入后触发其他规则。
"显示项目"
日程表组仅包含一条规则,"项目方式"
对于当前 KIE 会话工作内存顺序的每个购买,规则会根据规则文件中定义的文本区域将详情记录到 GUI 底部的文本区域。
规则"显示方式"
"评估"
日程表组还从 "Explode Cart"
规则获得。此日程表组包含两个规则 :"Free Fish Food Sample"
和 "Suggest Tank"
,按该顺序执行。
规则"Free Fish Food Sample"
只有在以下条件都满足时,才会触发 "Free Fish Food Sample"
规则:
如果顺序事实满足所有这些要求,则创建一个新产品(Fish Food Sample)并添加到工作内存中的顺序中。
规则"Suggest Tank"
只有在以下条件满足时才触发 "Suggest Tank"
规则:
当规则触发时,它会调用规则 文件中定义的 requireTank()
函数。此函数会显示一个对话框,询问用户是否是她或他想要购买玻里程表。如果用户确实有,则会在工作内存中的订购列表中添加一个新芬兰的 tank 产品
。当规则调用 requireTank()
函数时,该规则会传递帧的全局变量,以便该函数能够处理 Swing GUI。
Pet Store 示例中的 "do checkout"
规则没有日程表组,没有条件,因此该规则始终执行并被视为默认 MAIN
更新组的一部分。
规则 "do checkout"
rule "do checkout" when then doCheckout(frame, kcontext.getKieRuntime()); end
rule "do checkout"
when
then
doCheckout(frame, kcontext.getKieRuntime());
end
当规则触发时,它会调用规则 文件中定义的 doCheckout()
函数。此函数显示一个对话框,询问用户是否她或他想要签出。如果用户确实如此,则重点设置为 结账
员组,使该组中的规则启用(可能)触发。当规则调用 doCheckout()
函数时,该规则会传递 帧
全局变量,以便该函数能够处理 Swing GUI。
本例还演示了故障排除技术(如果结果未按预期一样执行):您可以从规则的 when
语句中删除条件,并在 then
语句中测试操作以验证操作是否正确执行。
"检查"
日程表组包含三个规则,用于处理订单并申请任何折扣:" 总额"、
和 "
应用 5% 的折扣""应用 10% 的折扣
"。
规则"总额"、"Apply 5% 的折扣"和"Apply 10% 的折扣"
如果用户还没有计算总额的单位,Grossing Total
accate the product 总计(将总值放在 KIE 会话中),并使用 textArea
global 变量通过 Swing JTextArea
显示它。
如果总额介于 10
到 20
左右,则 "Apply 5% discount"
规则计算总折扣,将其添加到 KIE 会话中,并将其显示在文本区域中。
如果总总额不低于 20
,"Apply 10% discount"
规则计算总额,将其添加到 KIE 会话中,并在文本区域中显示它。
pet Store 的执行示例
与其他红帽决策管理器决策示例类似,您可以通过运行 org.drools.examples.petstore.PetStoreExample
类作为 IDE 中的 Java 应用程序来执行 Pet Storeample 类。
当您执行 Pet Store 示例时,会显示 Pet Store Demo
GUI 窗口。此窗口显示可用产品列表(左下)、选定产品的空列表(右、Checkout 和 Reset 按钮(middle))和一个空系统消息区域(bottom)。
图 21.14. 启动后 pet Store 示例 GUI
本例中发生以下事件来建立此执行行为:
-
main()
方法已运行并加载规则基础,但尚未触发规则。目前,这是与运行的规则连接中的唯一代码。 -
新的
PetStoreUI
对象已创建,并为规则基础赋予句柄,供以后使用。 - 各种 Swing 组件已执行其功能,并显示初始 UI 屏幕并等待用户输入。
您可以从列表中点各种产品以浏览 UI 设置:
图 21.15. 探索 Pet Store 示例 GUI
还没有触发规则代码。UI 使用 Swing 代码来检测用户鼠标点击并将所选产品添加到用于 UI 右上角显示的 TableModel
对象中。本例演示了 Model-View-Controller 设计模式。
当您点 Checkout 时,规则会按以下方式触发:
-
CheckOutCallBack.checkout()
方法由 Swing 类调用(事件),等待用户点击 Checkout。这会将TableModel
对象(UI 右上角)中的数据插入到 KIE 会话工作内存中。然后,该方法会触发规则。 "Explode Cart"
规则是第一个触发,auto-focus
属性设为true
。通过 cart 中的所有产品的规则循环,确保产品处于工作内存中,然后提供"显示项目"和"
评估"
日程表组来触发的选项。这些组中的规则将 cart 的内容添加到文本区域(bottom)中,评估您是否有资格获得免费的放大分,并确定是否希望购买欺诈。图 21.16. 芬兰 tank 资格
-
"do checkout"
规则是下一个需要触发的,因为其他任何日程组当前没有关注,因为它是默认的MAIN
日程小组的一部分。这个规则始终调用doCheckout()
函数,它会询问您是否要签出。 -
doCheckout()
函数将焦点设置为"checkout"
Table 组,该组中的规则给出了要触发的选项。 -
"检查"
日程表组中的规则显示车队的内容,并应用相应的折扣。 然后,等待用户输入可选择更多产品(并导致规则再次触发),或关闭 UI。
图 21.17. 所有规则触发后的 pet Store 示例 GUI
您可以添加更多 System.out
调用来在 IDE 控制台中演示此事件流:
IDE 控制台中的 system.out 输出
Adding free Fish Food Sample to cart SUGGESTION: Would you like to buy a tank for your 6 fish? - Yes
Adding free Fish Food Sample to cart
SUGGESTION: Would you like to buy a tank for your 6 fish? - Yes