如何在Drools规则中识别非获胜者并执行setWinner(false)?
如何在Drools规则中识别非获胜者并执行setWinner(false)?
嗨,看起来你已经把胜者的规则逻辑搭得差不多了,要处理非胜者的标记其实有几个很实用的方案,我给你拆解一下:
方案一:初始化所有人为非胜者(最简洁推荐)
这个思路是先把所有人默认设为非胜者,之后只需要把符合条件的胜者改成true就行,不用专门再去处理非胜者,逻辑更清爽,也能避免复杂的匹配。
你可以加一个优先级最高的初始化规则,确保它最先执行:
rule "Initialize all as non-winners" salience 20 // 设高优先级,保证最先执行 when $p : Person(winner == null) // 用null判断避免重复初始化,如果你初始是其他值就对应调整 then $p.setWinner(false); update($p); end
然后把你原来的两个胜者规则的salience调整一下,比如把"Bob wins"设为10,"Oldest person wins"设为0,这样初始化规则跑完后,再执行胜者标记逻辑。这样一来,所有非胜者默认已经是false,只有符合条件的人会被改成true,完全不用额外写非胜者的处理规则,省事不少。
方案二:针对胜者场景单独处理非胜者
如果你不想用初始化的方式,也可以在确定胜者之后,专门给不符合胜者条件的人标记为false。这里要注意规则的执行顺序,必须等胜者规则跑完再执行非胜者的规则,所以要把非胜者规则的salience设得更低。
比如对应「Bob是胜者」的场景:
rule "Mark non-Bob people as non-winners" salience -15 // 优先级低于Bob的胜者规则 when Person(name == "Bob", winner == true) // 确认Bob已经被标记为胜者 $nonWinner : Person(name != "Bob", winner != false) // 只处理还没设为非胜者的人 then $nonWinner.setWinner(false); update($nonWinner); end
对应「无Bob时最年长者是胜者」的场景:
rule "Mark non-oldest people as non-winners" salience -20 // 优先级低于最年长者的胜者规则 when not Person(name == "Bob") // 确定没有Bob的情况 $oldestWinner : Person(winner == true) // 已经标记好最年长者为胜者 $nonWinner : Person(age != $oldestWinner.getAge(), winner != false) then $nonWinner.setWinner(false); update($nonWinner); end
方案三:通用型非胜者处理规则
还有一种更通用的写法,不管是哪种胜者场景,只要有一个人被标记为true,就把其他人设为false:
rule "Mark all non-winners as false" salience -20 when $winner : Person(winner == true) // 只要存在已经标记的胜者 $nonWinner : Person(winner != true, winner != false) // 排除已经处理过的和胜者本身 then $nonWinner.setWinner(false); update($nonWinner); end
小提醒
不管用哪种方案,都要注意update($p)的使用——它会触发规则引擎重新匹配事实,所以一定要在规则的when条件里加上类似winner != false的判断,避免规则无限循环执行哦。
备注:内容来源于stack exchange,提问作者Qwerky
相关产品推荐
相关产品推荐

