65.9K
CodeProject 正在变化。 阅读更多。
Home

对自定义规则引擎的内省

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.91/5 (5投票s)

2017年2月9日

CPOL

6分钟阅读

viewsIcon

16684

自定义规则引擎 - 声明式编程。

摘要

在规则引擎中定义规则是一种声明式编程,其中业务逻辑维护在主软件组件之外。构建规则引擎的方法多种多样,其使用方式也多种多样。虽然看似简单,但随着系统在企业中的重要性日益增加,它会带来严峻的挑战。问题范围广泛,包括但不限于规则引擎的构思、规则的语义、编写、可测试性以及变更管理。

引言

当需要频繁关注且上市时间是优先考虑的逻辑时,可以使用声明式方法构建应用程序逻辑。以这种方式构建应用程序要求决策者了解所有好处和后果。本文叙述了自定义规则引擎从策略到维护的生命周期。

Cadence

当需求明确且相互依赖性较低时,就会出现构建规则引擎的情况。使用条件和操作以声明式方式表达很容易。典型的规则

If  A > B  then return X + 1

因此,编写一个简单的规则引擎需要一个系统来选择规则、评估其条件并执行该规则中定义的后续操作。

像保险承保或产品税收计算这样需求不断变化的业务领域,需要一个能够轻松快速适应变化的系统。基于规则的系统是满足这一需求的最佳选择。不应试图使用规则来构建整个领域问题,这会使系统难以理解和维护。不应使用规则构建完整的领域,而是最好查看哪些逻辑部分不必更改,哪些系统部分会更改。规则方法可以应用于系统中频繁变化的部分,从而将规则在系统中的足迹降到最低。

影响构建基于规则的系统的另一个方面是这样一种误解,即业务用户或在产品范式中处于技术人员之上地位的用户可以轻松地对系统进行更改。然而,在许多情况下,事实并非如此,通常需要专业人员来维护规则系统。由于规则会在企业中引入一种新语言,因此保留知识成为一项额外的责任。

规则缩短了问题域与领域产品所有者之间的语义差距。

构建复杂性

可以使用脚本或基于规则的方式进行声明式编程。脚本功能强大,但非技术用户难以理解。构建基于规则的系统需要两部分:规则和执行规则的规则引擎。

在系统中,规则是产生结果或不产生结果的单个原子操作。规则具有作为过滤器工作的条件,这些条件决定了规则是否应参与请求上下文。规则的操作可能很简单,如返回一个值或调用其他软件组件,或者依赖于另一条规则。

Rule => If  A > B then X +1

规则条件(也称为过滤器)可能依赖于其他规则,这增加了系统中规则执行顺序的复杂性。在上面的表达式中,如果AB是直接值,那么规则引擎就很容易进行评估。如果AB依赖于另一条规则,那么系统执行就必须分阶段进行。首先,引擎必须评估AB,然后执行规则。

Rule => If  A > B then X + 1

规则操作可能依赖于另一条规则。这称为链式调用。在上面的表达式中,X是另一条规则(称为子规则)。构建有两种策略。

子规则与调用规则完全独立

这是最简单、最容易理解规则的方式。在这种方法中,规则引擎只需要执行一次规则。在这种情况下,X始终执行一次,并且可以在所有引用它的地方被引用,而无需进一步评估。

子规则知道父规则的上下文

这种方法使规则更加通用,并促进了重用,但它模糊了底层编程过程/函数范例。需要在父规则的上下文中多次执行的规则是不同的。

加载、解释和执行规则的规则引擎需要为性能而设计。在规则引擎的实现中,内存通常被用于换取性能。规则引擎需要预先将规则分成组。例如,如果一个系统中有 10,000 条规则,那么每次请求都评估和执行所有规则是不明智的。解决这个问题的方法是将规则分组到一个与问题域密切相关的段中。

R =  U( r(1), r(2), r(3), … r(i),….r(n) )

可以使用更详细的技术来评估规则,例如使用 Rete 算法。大多数商业规则引擎都支持 Rete 算法的实现。机器学习/神经网络可以应用于分段过程。

编写

处理规则语义和引擎的创建问题只是硬币的一面。另一面是为用户提供一个有意义的平台来定义规则。该媒介应该帮助用户理解并帮助他们定义带有所有语法的规则。它还应该表达规则之间的关系。

向系统中添加规则很容易,但最好设置指南,将规则根据问题域进行逻辑分段。这使得理解规则和维护它们更容易。

规则可以由多人编写,因此共同的设计指南和相同的沟通是必要的。规则的重复结构必须被记录下来并归类为模式。它促进了一致性,并且易于沟通复杂的规则关系。

规则语义应该支持时间顺序要求,例如,如果税率发生变化,那么规则系统可能必须保留此事件的知识,以便根据日期计算税款。

可测试性

定义的规则是针对语义进行测试,而不是逻辑测试,因此很难预测其正确性。即使是单个规则的更改也可能影响所有依赖规则的行为。因此,最好在构建活动的早期阶段就考虑规则系统和规则引擎的可测试性。

由于没有编译器支持和解释器支持规则,因此很容易出现诸如循环引用之类的问​​题。系统应该能够提前识别这种情况。

引擎需要支持仪器化和跟踪功能来进行监控。应该有足够的测试场景来支持所有规则,但这说起来容易做起来难,因为随着规则结构相互依赖深度的增加,循环复杂度会成比例增加。

变更管理

通常,规则引擎的出现是为了满足快速更改业务规则的需求。然而,规则的更改并非易于部署到生产系统中。旧规则需要被正确地淘汰和存档。新规则的添加或修改应该传播到规则引擎的缓存中。

设计一个可以增量或选择性地更新规则引擎的系统是困难的。通常,引擎会被缓存,并且对底层规则的任何更改都可能需要引擎丢弃缓存并重新构建。Rete 算法的实现可以解决这些选择性升级规则的问​​题。

结论

很容易看到构建规则引擎来解决当前问题的必要性。然而,必须理解上下文,并且必须提前规划实施后和维护事宜。

参考文献

© . All rights reserved.