我正在审核一个使用所谓规则引擎的项目.简而言之,它是一种从应用程序代码中外部化业务逻辑的方法.
这个概念对我来说是全新的,我对此持怀疑态度.在听过人们谈论过去几年的贫血领域模型后,我正在质疑规则引擎方法.对我来说,它们似乎是一种弱域模型的好方法.例如,我说我正在做一个与规则引擎交互的java webapp.然后我决定我想要一个基于同一个域的Android应用程序.除非我希望Android应用程序也与规则引擎交互,否则我将不得不错过已编写的任何业务逻辑.
由于我对它们没有任何经验,只是好奇,我有兴趣了解使用规则引擎的优点和缺点?我能想到的唯一一个专业是你不需要重建你的整个应用程序只是为了改变一些业务规则(但实际上,有多少应用确实有那么多变化?).但是使用规则引擎来解决这个问题对我来说就像在霰弹枪伤口上放一个创可贴一样.
更新 - 自写这篇文章以来,上帝本人Martin Fowler一直在博客上谈论使用规则引擎.
我见过的大多数规则引擎都被系统代码视为黑盒子.如果我要构建域模型,我可能希望某些业务规则是域模型固有的,例如业务规则告诉我对象何时具有无效值.这允许多个系统共享域模型而不重复业务逻辑.我可以让每个系统使用相同的规则服务来验证我的域模型,但这似乎削弱了我的域模型(正如问题中指出的那样).为什么?因为我不是始终在所有系统中始终如一地执行业务规则,而是依靠系统程序员来确定何时应该强制执行业务规则(通过调用规则服务).如果域模型完全填充您,这可能不是问题,但如果你'你可能会有问题
还有另一类业务规则:决策制定.例如,保险公司可能需要对承销申请人的风险进行分类并获得溢价.您可以将这些类型的业务规则放在域模型中,但是对于这样的场景的集中决策通常是可取的,并且实际上非常适合面向服务的体系结构.这确实提出了为什么规则引擎而不是系统代码的问题.规则引擎可能是更好选择的地方是负责决策的业务规则随着时间的推移而变化(正如其他一些答案所指出的那样).
规则引擎通常允许您在不重新启动系统或部署新的可执行代码的情况下更改规则(无论您从供应商那里获得什么承诺,都要确保在非生产环境中测试您的更改,因为即使规则引擎完美无瑕,人类仍在改变规则).如果您正在考虑"我可以通过使用数据库存储更改的值来实现这一点",那么您是对的.规则引擎不是一个做出新事物的神奇盒子.它旨在成为一种提供更高抽象级别的工具,因此您可以更少地专注于重新发明轮子.许多供应商通过让您创建模板来使这一点更进一步,以便业务用户可以填写空白而不是学习规则语言.
关于模板的一个谨慎之处:模板永远不会比没有模板编写规则花费更少的时间,因为模板必须至少描述规则.计划更高的初始成本(与构建使用数据库存储更改值而不是直接在系统代码中编写规则的系统相同) - ROI是因为您节省了系统代码的未来维护.
我认为您对贫血领域模型的担忧是有效的.
我见过两个应用程序,一个着名的商业Rete规则引擎在我工作的生产中运行.我认为一个成功,另一个失败.
成功的应用程序是一个决策树应用程序,由~10棵树组成,每棵树约有30个分支点.规则引擎具有允许业务人员维护规则的UI.
不太成功的应用程序有大约3000条规则被抨击到规则数据库中.没有人知道在添加新规则时是否存在冲突的规则.对Rete算法的理解很少,而且产品的专业知识已经离开了公司,所以它变成了一个不可触及且不可挽回的黑匣子.部署周期仍受规则更改的影响 - 必须在更改规则时执行完整的回归测试.记忆也是一个问题.
我会轻描淡写地说.当规则集的大小适中时,很容易理解更改,例如上面给出的简单电子邮件示例.一旦规则数量攀升到数百个,我认为你可能会遇到问题.
我还担心规则引擎会成为您应用程序中的单例瓶颈.
我认为使用对象作为分区规则引擎空间的方法并没有错.在遵循私有规则引擎的对象中嵌入行为对我来说似乎没问题.当规则引擎需要不正确触发其对象一部分的状态时,问题就会出现.但这只是设计难度的另一个例子.
在某些情况下,规则引擎可以提供很多价值.
首先,许多规则引擎以更具声明性的方式工作.一个非常粗略的例子是AWK,您可以在其中将正则表达式分配给代码块.当文件扫描程序看到正则表达式时,将执行代码块.
你可以看到,在这种情况下,如果你有一个大的AWK文件并且你想添加Yet Another"规则",你可以很容易地找到文件的底部,添加你的正则表达式和逻辑,并完成它.具体来说,对于许多应用程序,您并不特别关注其他规则正在做什么,并且规则实际上并不是彼此互操作.
因此,AWK文件变得更像"规则汤".这种"规则汤"性质使得人们可以非常关注他们的域,而不必担心系统中可能存在的所有其他规则.
例如,弗兰克对总价超过1000美元的订单感兴趣,因此他投入了他感兴趣的规则系统."如果order.total> 1000那么电子邮件弗兰克".
同时,莎莉想要来自西海岸的所有订单:"IF order.source =='WEST_COAST'那么电子邮件莎莉".
所以,你可以在这个琐碎的,人为的案例中看到,一个订单可以满足两个规则,但两个规则是相互独立的.来自西海岸的1200美元订单通知Frank和Sally.当弗兰克不再担心时,他只会简单地将他的规则从汤中拉出来.
在许多情况下,这种灵活性可以非常强大.它也可以像这种情况一样,向最终用户公开简单的规则.使用高级表达式和轻量级脚本.
现在,很明显,在一个复杂的系统中,可能会发生各种各样的相互关系,这就是整个系统不是"完成规则"的原因.某个人,某个地方将负责规则而不是失控.但这并不一定会降低系统可以提供的价值.
请注意,这甚至不涉及专家系统,其中规则触发规则可以创建的数据,但是更简单的规则系统.
无论如何,我希望这个例子能够说明规则系统如何帮助扩展更大的应用程序.
我见过的规则引擎最大的专业是它让业务规则所有者实现业务规则,而不是把责任放在程序员身上.即使您有一个敏捷的流程,您不断获得利益相关方的反馈并进行快速迭代,但仍然无法达到通过让业务规则实施的人员实现的效率水平.
此外,如果规则嵌入在代码中,则不能强调删除可能由简单规则更改导致的重新编译 - 重新测试 - 重新部署周期的值.通常有几个团队参与将祝福放在构建上,并且使用规则引擎可以使大部分内容变得不必要.
我为客户编写了一个规则引擎.最大的胜利是包括所有利益相关者.引擎可以运行(或重放)查询并解释文本中发生的情况.商务人士可以查看文本描述并快速指出规则,例外和其他特殊情况的细微差别.一旦涉及业务方面,验证就会变得更好,因为很容易获得他们的意见.此外,规则引擎可以与应用程序代码库的其他部分分开存在,因此您可以跨应用程序使用它.
可以肯定的是,一些程序员不喜欢学习太多东西.规则引擎和你放入它们的规则,以及实现它们的东西,可能有点毛茸茸.虽然一个好的系统可以很容易地处理生病和扭曲的逻辑网络(或经常是不合逻辑的),但它并不像编写一堆if
语句那么简单(无论一些简单的规则引擎做什么).规则引擎为您提供了处理规则关系的工具,但您仍然必须能够想象所有这些在您的脑海中.有时候就像生活在电影" 巴西"中一样.:)
它(作为其他一切)取决于您的应用程序.对于某些应用程序(通常是永不改变的规则或规则在实际生命常数上最好的应用程序,即不会明显改变,例如物理属性和公式),使用规则引擎没有意义,它只是引入了额外的复杂性,并要求开发人员拥有更大的技能.
对于其他应用程序,这确实是一个好主意.例如,订单处理(订单是从发票到处理货币交易的任何东西),不时地对某些相关法律或代码(在司法意义上)进行一分钟更改,要求您满足新的要求(例如销售税) ,经典).而不是试图强迫你的旧应用程序进入这种突然你必须考虑销售税的新情况,而不是之前的情况,更容易调整你的规则集而不是干涉潜在的大你的代码集.
然后,当地政府的下一个修订要求在一定标准内报告所有销售,而不是你必须加入并添加.最后,你会得到非常复杂的代码,当你转身并希望恢复其中一条规则的效果时,这些代码很难管理,而不会影响所有其他规则......
到目前为止,每个人都对规则引擎非常积极,但我建议读者要小心.当问题变得有点复杂时,您可能会突然发现整个规则引擎已被渲染为不合适,或者比使用更强大的语言复杂得多.此外,对于许多问题,规则引擎将无法轻松检测到大大减少评估条件的运行时和内存占用的属性.在相对较少的情况下,我更喜欢规则引擎到依赖注入框架或更动态的编程语言.