我想解雇所有规则并退出。在我的例子中,我只有2条规则,但它们是相互关联的,即规则2应该在规则1之后被解雇。
问题是它只打印出规则1的输出。此外,它看起来像进入循环并在内部打印出相同的消息(Client is interested in skiing
)。
package com.sample;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
/**
* This is a sample class to launch a rule.
*/
public class TestSimpleRules {
public static final void main(String[] args) {
try {
// load up the knowledge base
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
// go !
Client client = new Client();
Season season = new Season();
client.addProduct("snowboard");
client.addProduct("ski poles");
season.setSeason("winter");
kSession.insert(client);
kSession.insert(season);
kSession.fireAllRules();
} catch (Throwable t) {
t.printStackTrace();
}
}
public static class Client {
private Set<String> buyingHistory;
private String interestedIn;
public Client()
{
buyingHistory = new HashSet<String>();
}
public Set<String> getBuyingHistory() {
return this.buyingHistory;
}
public void addProduct(String product) {
this.buyingHistory.add(product);
}
public String getInterestedIn() {
return this.interestedIn;
}
public void setInterestedIn(String interestedI) {
this.interestedIn = interestedIn;
}
}
public static class Season {
private String currentSeason;
public String getSeason() {
return this.currentSeason;
}
public void setSeason(String season) {
this.currentSeason = season;
}
}
}
规则:
package com.javacodegeeks.drools;
import com.sample.TestSimpleRules.Client;
import com.sample.TestSimpleRules.Season;
rule "Rule #1"
when
c : Client( Client.getBuyingHistory() contains "snowboard", thisBuyingHistory : buyingHistory) and
s: Season( Season.getSeason() == "winter" )
then
System.out.println( thisBuyingHistory );
c.setInterestedIn("skiing");
System.out.println("Client is interested in skiing");
update( c );
end
rule "Rule #2"
when
c: Client( Client.getInterestedIn() == "skiing" && !(Client.getBuyingHistory() contains "ski jacket"), thisBuyingHistory : buyingHistory)
then
System.out.println("Ski jacket is recommended");
end
答案 0 :(得分:0)
首先是几个技术细节:
and
,这是隐含的。modify
更新事实。not contains
,因此您不需要编写否定约束。(以上所有内容均可从Drools手册中学习。)
rule "Rule #1"
when
c: Client( buyHist: buyingHistory contains "snowboard" )
s: Season( season == "winter" )
then
System.out.println( buyHist );
modify( c ){ setInterestedIn("skiing") }
System.out.println("Client is interested in skiing");
end
rule "Rule #2"
when
c: Client( interestedIn == "skiing",
buyingHistory not contains "ski jacket" )
then
System.out.println("Ski jacket is recommended");
end
触发第一条规则的循环是由于字段interestedIn
的修改,导致重新评估涉及某些Client
事实的所有规则。由于"Rule #1"
没有限制它取消发射资格,它再次发射。安全的补救措施是仅在interestedIn
不等于"skiing"
时限制规则才会触发:
rule "Rule #1"
when
c: Client( buyHist: buyingHistory contains "snowboard"
interestedIn != "skiing" )
s: Season( season == "winter" )
then ... end
还有其他方法可以处理这种情况。规则属性no-loop
并非如此安全。检查上述文档以了解其他选项。