我对此很好奇:

在微软的 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 Guy,BTW)

有帮助吗?

解决方案

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

例子包括
付钱:
规则内, 业务规则引擎, ASA 业务规则引擎

开源:
开放规则, 流口水

还有很多。包括一些内置于java(Java规则引擎API(JSR94))和.Net(Windows Workflow Foundation规则引擎)。

但不确定直接 PHP。

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

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

我还走上了为小型系统编写自己的道路。就我而言,我使用了 javascript,并在执行与表单一起保存的脚本之前,使用发布页面中的数据简单地设置了变量。

这在较小的规模上也是有效的,但我将其限制为仅给出简单的“继续”/“不继续”响应。

其他提示

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

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

第一种方法很简单,我认为不需要解释。但是,如果您需要帮助,请告诉我,我将详细说明该想法。让我解释一下第二种方法:

在进一步讨论之前,请先阅读一些有关 Rete 算法的内容。

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

规则1:IF (message.date 等于 24.10.2009) AND (message.title 包含“hello”) THEN 做某事1

规则2:IF (message.hasAttachement 为 TRUE) AND (message.date 等于 24.10.2009) THEN 做某事2

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

  • C1:(消息.日期等于 2009 年 10 月 24 日)
  • C2:(message.title 包含“你好”)
  • C3:(message.hasAttachment 为 TRUE)

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

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

最复杂的部分是测试网络。如果您只想在规则中使用逻辑 AND(没有其他逻辑操作或括号),那么这是微不足道的。但是,如果您想要更复杂的构造,那么您将必须编写大量代码并进行大量测试。

有关雷特的更多信息:

  • 大型学习系统的生产匹配/--Robert B.多伦博斯。(1995)
  • 论生产系统的高效实施/-- Charles L.福吉 (1979)

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

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

将规则链接到 责任链.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top