О, Drools знает, как и когда оценивать ваши правила, уверен, что делает ... Единственное, что вы должны сообщить ему, когда что-то изменится в вашей модели.
Сеттеры, которые вы вызываете в правой части ваших правил, никогда не уведомляются Drools, поэтому он не знает об изменениях, которые вы внесли.
В Drools есть специальное ключевое слово modify
, которое сообщает движку, когда что-то меняется в вашей модели.
Правила, которые устанавливают область и континент, должны выглядеть следующим образом (в зависимости от используемой вами версии Drools вы можете начать испытывать бесконечные циклы при использовании modify
. Я переписал левую часть вашего правила, чтобы их избежать):
rule "UK"
when
$c:Country(
area == null,
continent == null,
id in (CountryID.UNITED_KINGDOM)
)
then
modify($c){
setArea(EconomicAreaID.EU),
setContinent(ContinentID.EUROPE)
};
end
Теперь, вторая проблема в том, что в правилах, устанавливающих заряд, Country
вложено в ваши ChargeRequest
объекты. Слюни не будут автоматически понимать, что когда вы изменяете Country
, он должен пересмотреть правила, связанные с ChargeRequests
. Вы должны сделать это явно:
rule "EU to EU"
when
$rr:ChargeRequest(
$origin: origin,
$destination: destination
)
Country(
this == $origin,
area == EconomicAreaID.EU
)
Country(
this == $destination,
area == EconomicAreaID.EU
)
then
$rr.setCharge(1);
end
Как видите, Друльс умен, но вы должны немного ему помочь;)
Лучшим подходом при работе с параметризованными значениями такого типа в соответствии с фиксированным набором условий является моделирование самого условия как факта:
1.- Создайте класс для моделирования ограничений и результатов:
public class RequestCharge{
private EconomicAreaID origin;
private EconomicAreaID destination;
private double charge;
//getters and setters
}
2.- Вставьте все ограничения в ваш сеанс:
kSession.insert(new RequestCharge(EconomicAreaID.EU, EconomicAreaID.EU, 1.0);
kSession.insert(new RequestCharge(EconomicAreaID.US, EconomicAreaID.US, 2.0);
kSession.insert(new RequestCharge(EconomicAreaID.EU, EconomicAreaID.US, 3.0);
kSession.insert(new RequestCharge(EconomicAreaID.US, EconomicAreaID.EU, 4.0);
3.- Имейте одно правило для обработки всех запросов (вы можете добавить дополнительное правило для обработки запросов, которые не соответствуют ни одному из настроенных RequestCharges
):
rule "Apply Charge"
when
$rr:ChargeRequest(
$origin: origin,
$destination: destination
)
$o: Country( //You still need these Country patterns to react to the changes in the first rule
this == $origin
)
$d: Country(
this == $destination
)
RequestCharge(
origin == $o,
destination == $d,
$charge: charge
)
then
$rr.setCharge($charge);
end
Надеюсь, это поможет,