Drools - 在规则条件或结果内做复杂的事情
在我的公司,我们计划在几个项目中使用 Drools BRE。现在我们尝试定义一些最佳实践。
我的问题是在规则条件/结果中应该做什么和不应该做什么。 假设我们可以直接编写Java或调用方法(例如来自工作内存中的全局对象)。
例子。给定一个评估通用对象(例如 Person)的规则,其属性设置为 true。现在,只能为该对象定义该特定属性,该对象将进入数据库并获取该信息。因此,我们有两种实现方法:
替代方案 A:
- 访问数据库并获取对象属性(真/假,代码)
- 将对象插入工作内存中
- 评估规则
替代方案B:
- 插入一个全局对象,该对象具有连接到数据库的方法并检查给定对象的属性。
- 在工作内存中插入要 eval 的对象
- 在规则中,调用全局对象并执行对数据库的访问
哪一个被认为更好?我真的很喜欢 A,但有时 B 更简单,但是如果引发数据库异常之类的情况会发生什么?
我已经在 Packt Publishing 的 Drools 5.0 书中看到了替代方案 B 的实现,但是他们只是在进行嘲笑,并且根本没有谈论访问数据库的实际含义。
谢谢你,
In my company we are planning to use Drools a BRE for couple of projects. Now we trying to define some best-practices.
My question is what should be and shouldn't be done inside a Rule Condition/Consequence.
Given that we can write Java directly or call methods (for example From a Global object in the Working Memory).
Example. Given a Rule that evaluates a generic Object (e.g. Person) have property set to true. Now, that specific propertie can only be defined for that Object going to the database and fetching that info. So we have two ways of implementing that:
Alternative A:
- Go to the database and fetch the object property (true/false, a code)
- Insert the Object in the working memory
- Evaluate the rule
Alternative B:
- Insert a Global Object that has a method that connects to the database and check for the property for the given object.
- Insert the Object to eval in Working Memory
- In the rule, call the Global Object and perform the access to the database
Which of those is considered better? I really like A, but sometimes B is more straightforward, however what would happen if something like a Exception from the Database is raised?
I have seen the alternative B implemented in the Drools 5.0 Book from Packt Publishing,however they are doing a mocking and they don't talk about the actual implications of going to the database at all.
Thank you,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于规则的事情之一是它们可以被执行很多很多次。特别是如果您的规则条件出现错误。这显然会对性能产生影响。
我倾向于选择选项 A,在外面准备好你的事实,然后将它们插入工作记忆中进行评估。
当然,也可以选择将规则划分为数据加载规则,然后进行业务规则评估(例如使用规则流)。
这将为您提供在代码之外填充数据的声明性控制。
One of the things about rules is that they can be executed many, many times. Particularly if you make an error with your rule conditions. That obviously has a performance impact.
I'm inclined then to prefer option A, prepare your facts outside, and insert them into working memory for evaluation.
Certainly, there is also the option of partitioning the rules into data loading rules then business rule evaluation (using Rule flow for instance).
That would give you declarative control of populating your data outside of code.
我还需要从其他系统(数据库、服务调用等)获取外部数据,所以我对此进行了一些处理。就我个人而言,我会根据您是否知道您预先需要哪些事实来做出决定。如果是这样,那么无论如何,请随意使用 Java 进行调用。这将使您能够更好地处理错误。如果无法检索某些数据意味着无法运行规则引擎,那么您将避免创建会话、插入事实、设置全局变量等工作。如果你只是要暂停(),那么启动它是没有意义的。
但当然也有一些情况,无法检索数据不应阻止您运行。在某些情况下,替代方案 A 和 B 的效果同样好。但假设需要某些数据取决于其他事情。例如,我正在开发一个应用程序,该应用程序评估本质上是大型逻辑树,并使用来自服务调用的数据来评估叶子。如果两个叶子被“与”在一起,那么两个叶子都必须为真,它们的分支才为真,一旦其中一个评估为假,该分支就会变成假,我不再需要评估另一个叶子。这意味着预先加载评估它所需的数据是一种浪费。 “按需”检索数据是像 Jess 这样的规则引擎也支持向后链接<的原因之一/a> 除了默认的正向链接之外。
在 Drools 中的向后链接完成之前,我看到的替代方案是建议正在使用 "from" 关键字。我对此很幸运,但有两件事需要考虑:
我希望这有帮助。如果有什么我可以澄清或扩展的,请告诉我。
I also have a need to grab external data from other system (database, service calls, etc) so I've dealt with this a bit. Personally, I would make that decision based on whether you will know what facts you will need up front. If so, then by all means, feel free to make your calls in Java. This will allow you to do better error handling. And if not being able to retrieve certain data means that running the rule engine is a no-go, you will avoid the work of creating the session, inserting facts, setting globals and so on. No sense in starting it if you're just going to halt().
But of course there are also cases where not being able to retrieve data shouldn't stop you from running. In some of those cases, Alternative A and B would work equally well. But suppose that needing certain data depends on other things. For example, I work on an application that evaluated what are essentially big logic trees and the leafs are evaluated using data from service calls. If two leafs were AND'd together so both had to be true for their branch to be true, as soon as one of them evaluated to false, that branch becomes false and I no longer need to evaluate the other leaf. That means that it would have been a waste to have pre-loaded the data I would have needed to evaluate it. Retrieving data "on demand" is one reason that rule engines like Jess also support backward chaining in addition to the default forward chaining.
Until backward chaining is complete in Drools, the alternative I've seen suggested is using the "from" keyword. I've had some luck with it but there are two things to consider:
I hope this helps. Let me know if there's anything I can clarify or expand on.