当我们尝试“Drools”时,我们遇到了Drools的问题。基于地图的模型的特征。
看来,在没有特质之后,基于地图的事实就会消失(或收回)。
使用特征属性来获取模型属性似乎没有任何问题。
在下面的场景中,期望是:
在规则5中,无论我是否添加了' bmi'特性的属性,并尝试设置和/或将属性放在基于地图的事实中,它仍然没有达到这个规则(或规则3之后的任何事情)。
我们正在尝试使用该模型,主要用于约束和更新,然后在规则中应用和使用特征为我们提供更强类型的事实和更容易的规则约束。
测试用例:
public class TraitDonningTest extends CommonTestMethodBase
{
@Test
public void should_see_map_after_don() throws IOException
{
final String rule = Files.asCharSource(new File("src/test/resources/rules/traits.drl"), Charset.defaultCharset())
.read();
KieSession ks = loadKnowledgeBaseFromString(rule).newKieSession();
TraitFactory.setMode(VirtualPropertyMode.MAP, ks.getKieBase());
MyModel model = new MyModel();
model.put("weight", 1.0);
ks.insert(model);
ks.fireAllRules();
//We should have an updated BMI here
assertEquals(3.0, model.get("bmi"));
}
/**
* The real model based off of a map
*/
public static class MyModel extends HashMap<String, Object>
{
}
}
规则:
package drools
import TraitDonningTest.MyModel
declare MyModel
@Traitable
end
declare trait MyTrait
@PropertyReactive
height : Double
weight : Double
end
rule "1 - Update Model"
when
$model: MyModel(
this['weight'] != null,
this['height'] == null )
then
modify($model) {
put('height', 2.0)};
System.out.println("Rule 1");
end
rule "2 - Apply Trait"
dialect "mvel"
no-loop
when
$model: MyModel(
this['weight'] != null,
this['height'] != null)
then
System.out.println("Rule 2A: " + $model.get('weight') + " (before don)");
MyTrait trait = don($model, MyTrait.class);
System.out.println("Rule 2B: " + $model.get('weight') + " (after don)");
System.out.println("Rule 2C: " + trait.weight );
end
rule "3 - Check Trait"
dialect "mvel"
when
$trait : MyTrait()
then
System.out.println("Rule 3: " + $trait.weight);
end
rule "4 - Check Model"
dialect "mvel"
when
MyTrait()
$model: MyModel()
then
System.out.println("Rule 4A: " + $model.get('height'));
System.out.println("Rule 4B: " + $model.get('weight'));
end
rule "5 - Compute Map"
when
$model : MyModel()
MyTrait(
$height : height,
$weight : weight)
then
double compute = $height + $weight;
modify($model) {
put('bmi', compute)};
System.out.println("Rule 5: " + $model.get('bmi'));
end
rule "6 - Summarize Results"
when
$a: Number() from accumulate( MyModel(), count(1) )
$b: Number() from accumulate( MyTrait(), count(1) )
then
System.out.println("Model: " + $a);
System.out.println("Trait: " + $b);
end
输出:
Rule 1
Rule 2A: 1.0 (before don)
Rule 2B: 1.0 (after don)
Rule 2C: 1.0
Rule 3: 1.0
Model: 0
Trait: 1
更多细节和测试......
我尝试使用强类型类作为事实而不是地图。
如果我用强类型事实替换基于地图的事实,那么输出就是我所期望的:
Rule 1
Rule 2A: 1.0 (before don)
Rule 2B: 1.0 (after don)
Rule 2C: 1.0
Rule 3: 1.0
Rule 4A: 2.0
Rule 4B: 1.0
Rule 5: 3.0
Model: 1
Trait: 1
如果我使强类型事实(类)扩展HashMap,即使我在特征中有属性,它也会恢复为非工作结果集。
Rule 1
Rule 2A: 1.0 (before don)
Rule 2B: 1.0 (after don)
Rule 2C: null
Rule 3: null
Model: 0
Trait: 1