2

我很好奇这个:

在 Microsoft 的 Outlook Express(或 Outlook,记不太清了,我是 Mac 用户)中,他们有一些非常酷的东西。通用规则:

例如,您可以配置一组规则来自动排序或删除您的电子邮件。它功能强大且易于使用。

这些规则看起来很像这样:

“如果收件箱中的电子邮件主题包含“foo”、“bar”或“foobar”,请将其删除”

我需要为强大的表单验证系统编写类似的代码。开发人员应该能够简单地创建如下规则:

rule: [password_1] is_not_equal_with [password_2]
consequence: show_error '2921'

rule: [firstName] has_less_characters_than '2'
consequence: show_error '1211'

rule: [age] is_numeric, is_smaller_than '13', is_greater_than '130'
consequence: show_error '1522'

rule: [gender] is_equal_with 'female'
consequence: show_group [female_questions]

rule: [termsAndConditionsAccepted] is_not_checked
consequence: show_error '482'

rule: [age] is_less_than 21
consequence: hide_group [income_questions]

好吧,我有一些想法如何做到这一点,我会将它们发布在这里作为答案。但在我重新发明轮子之前:是否有任何书面概念可以用作开发类似于此的基于规则的验证系统的基础?或者,如果没有,您对如何做到这一点有什么建议吗?

在上面的示例中,方括号中的所有内容都是 html 表单元素的名称。撇号 '' 中的所有内容都是要比较的“硬编码”值。

定义的规则被翻译成 PHP 代码和 JavaScript 代码来进行客户端和服务器端验证。

它必须具备的功能:

  • 条件规则:A 依赖 B
  • 值比较:对于整数、浮点数、字符串
  • 也启用一些表单控制逻辑,例如上面的“[gender] is_equal_with 'female'”示例。

怎么可能做到这一点?从科学的角度来看,我必须考虑哪些实体?

我认为这个的理论概念是平台无关的。尽管我将在 PHP 和 JavaScript 中实现这一点,但 C++ 开发人员没有理由不响应 ;-)(我是 Objective-C 人,顺便说一句)

4

4 回答 4

4

您可能想查看一些开源规则引擎;甚至是付费的。

示例包括
付费:
InRule业务规则引擎ASA 业务规则引擎

开源:
OpenRulesDrools

还有很多。包括一些内置于 java (Java Rule Engine API (JSR94)) 和 .Net (Windows Workflow Foundation Rules Engine)。

虽然不确定直接的PHP。

附带说明一下,我使用了几个引擎,例如Haley Rules(在它们被 Oracle 收购之前)来驱动 Web UI。请注意,执行速度绝对至关重要。我们让 Haley 处理每个页面加载(抵押应用程序)大约 2000 条规则,并且它在 40 毫秒内执行(不是拼写错误)。我们用它来决定页面上有哪些字段,以及确定输入的数据是否一致、是否符合法律标准,甚至是否输入正确。

由于简单地实例化引擎需要多长时间,即使在更小的规则集上,其他一些引擎也会慢得多。

我还为较小的系统编写了自己的程序。在我的例子中,我使用了 javascript,并在执行与表单一起保存的脚本之前,简单地使用来自发布页面的数据设置变量。

这在较小的规模上也很有效,但我将其限制为仅给出简单的通过/不通过响应。

于 2010-01-11T17:42:34.493 回答
2

对于少量规则和消息,您可以应用蛮力算法:获取每条规则和每条消息并比较它们是否合适。您将得到 O(r m ) 复杂度,其中 r 是规则数,m 是消息数,不考虑规则可以有多个条件。

对于大量规则或消息,您可以实现 Rete 网络 ( http://en.wikipedia.org/wiki/Rete_algorithm )。这需要一些内存,但在实践中要快得多。根据您设计规则的方式,您将获得不同的复杂性。

第一种方法很简单,我想我不需要解释它。但是,如果您需要帮助,请告诉我,我会详细说明这个想法。让我解释第二种方法:

在继续之前阅读一些关于 Rete 算法的内容。

在 Rete 网络的 alpha 部分,您将存储出现在规则中的不同条件。一些规则可能共享一些条件。喜欢:

规则 1:如果(message.date 等于24.10.2009)和(message.title 包含“hello”)然后做某事1

规则 2:如果(message.hasAttachement 为 TRUE)并且(message.date 等于24.10.2009)然后做某事2

所以网络的 Alpha 部分将有 3 个元素

  • C1:(message.date 等于 24.10.2009)
  • C2:(message.title 包含“你好”)
  • C3:(message.hasAttachement 为 TRUE)

在 Beta 网络中,您将有两个连接节点,连接 C1-C2 和 C3-C1。

结束 beta 网络的生产节点将包含当消息满足规则的所有条件(在 alpha 部分)和所有一致性检查(在 beta 部分)时必须执行的一系列操作。

最复杂的部分是 beta 网络。如果您只想要规则中的逻辑 AND(没有其他逻辑运算或括号),那么这很简单。但是,如果您想要更复杂的构造,则必须编写大量代码并进行大量测试。

有关 Rete 的更多信息:

  • 大型学习系统的生产匹配/--Robert B. Doorenbos。(1995)
  • 关于生产系统的有效实施/--Charles L. Forgy (1979)
于 2010-01-11T18:01:30.180 回答
1

将规则链在责任链中

于 2010-01-11T17:42:47.567 回答
1

在面向对象的设计中,一种方法是实现命令模式,或者,对于更复杂的需求,实现解释器模式。您通常会为不同类别的规则创建多个类,并且可以为更复杂的场景组合它们(例如,通过构建 CompositeRule);它们都支持像 Execute() 或 Execute(context) 这样的接口。

您建立一个规则实例队列,并为每个作用的对象在每个实例上调用 Execute(context)。上下文将包含您正在操作的对象(消息、表单或其他)的实例。

于 2010-01-11T17:35:53.990 回答