【问题标题】:Drools: Rules involving a Map from String to ObjectDrools:涉及从字符串到对象的映射的规则
【发布时间】:2016-04-13 05:57:04
【问题描述】:

我需要帮助来编写 Drools 规则。我有两个名为 Context 和 CreditReport 的类。

在触发规则之前,上下文作为事实插入到知识会话中。

我需要编写一条规则,当信用评分超过 800 时,在控制台上打印“优秀”。

理想情况下,我会将 CreditReport 直接插入会话中,但遗憾的是我没有该选项。

我写的规则看起来不太好:

  1. then 部分有一个 if 语句
  2. 我正在将对象类型转换为 CreditReport

感谢您的帮助!

// Context.java

public class Context {
    private Map<String, Object> data = Maps.newHashMap();

    public <T> T getData(final String key, final Class<T> clazz) {
        return clazz.cast(data.get(key));
    }

    public void putData(final String key, final Object value) {
        this.data.put(key, value);
    }
}

// CreditReport.java

public class CreditReport {
    private final String name;
    private final int creditScore;

    public String getName() {
        return this.name;
    }

    public int getCreditScore() {
        return this.creditScore;
    }

}

//主要方法

context.put("creditReport", new CreditReport("John", 810));
session.insert(Arrays.asList(context));
session.fireAllRules();

// 规则

rule "Excellent_Score"
when Context($creditReportObject : getData("creditReport"))
then
    final CreditReport creditReport = (CreditReport) $creditReportObject;
    if (creditReport.getCreditScore() >= 800) {
       System.out.println("Excellent");
    }
end 

【问题讨论】:

    标签: java drools kie


    【解决方案1】:

    是什么让您插入包含单个 Context 对象的 List&lt;Context&gt;? Java代码应该这样做

    context.put("creditReport", new CreditReport("John", 810));
    session.insert( context );
    session.fireAllRules();
    

    规则现在可以写成

    rule "Excellent_Score"
    when 
       Context( $creditReportObject : getData("creditReport") )
       CreditReport( creditScore > 800 ) from $creditReportObject 
    then
       System.out.println("Excellent");
    end
    

    当然,您可以从 Context 获取并插入 CreditReport。 - 我怀疑你所展示的内容更令人费解,但“我没有那个选项”无论如何都是代码味道。

    编辑 出于多个原因打印“优秀”的单个规则可以像下面那样编写,尽管这并不比两个规则好多少,考虑到您可以包装 RHS到方法或 DRL 函数中。

    rule "Excellent_Score_2"
    when 
       Context( $creditReport : getData("creditReport"),
                $account: getData("account") )
       ( CreditReport( creditScore > 800 ) from $creditReport
         or
         Account( balance >= 5000 ) from $account )
    then
       System.out.println("Excellent");
    end
    

    【讨论】:

    • 谢谢劳恩!你在所有方面都是对的。一个后续问题。如果 Context 包含另一个名为 Account 的对象。我想编写一个规则,当 CreditReport.creditScore >= 800 或 Account.balance >= 5000 时打印“优秀”?我知道如何用 AND 关系而不是 OR 来编写规则。我也尽量避免使用 eval
    • 使用一条规则并没有什么好处 - 请参阅我的编辑。
    • 知道了。再次感谢! :)
    猜你喜欢
    • 2016-11-24
    • 2018-04-04
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 2019-09-18
    • 2021-02-24
    • 2023-03-30
    相关资源
    最近更新 更多