Skip to content

RuleBooks

Clayton Long edited this page Apr 19, 2017 · 3 revisions

RuleBooks chain Rules together and execute them as a group. A RuleBook can (optionally) have a single Result that is the product of the execution of all Rules in the RuleBook based on the facts they are evaluated against. In the past there was a distinction between RuleBooks, which did not have a Result, and DecisionBooks, which did have a Result. However, since there was so much overlap between RuleBooks and DecisionBooks, a single RuleBook interface now represents both RuleBooks that have a Result and RuleBooks that do not have a Result, the difference being whether or not a Result is expected. A Result is expected in a RuleBook if a default Result is set using the setDefaultResult() method.

All RuleBooks implement the RuleBook interface. And currently, rulebook-core only provides a single implementation of the RuleBook interface, CoRRuleBook, which uses the Chain of Responsibility pattern to chain Rules together.

Building a RuleBook

There are two basic ways to build a RuleBook: by extending a RuleBook implementation or by implementing/overriding the defineRules() method or by creating an instance of an existing RuleBook implementation and adding Rules externally. Variations on building a RuleBook, include RuleBookRunner, which is discussed in POJO Rules.

Building a RuleBook by implementing/overriding defineRules()

public class MyRuleBook extends CoRRuleBook {
  public void defineRules() {
    addRule(RuleBuilder.create()
      .when(facts -> facts.getValue("pet sound").equals("meow"))
      .then(facts -> facts.setValue("pet type", "cat"))
      .build());
    addRule(RuleBuilder.create()
      .when(facts -> facts.getValue("pet type").equals("cat"))
      .then(facts -> facts.setValue("leather furniture", false))
      .build());
  }
}

In the above example MyRuleBook is a subclass of CoRRuleBook. Buy implementing defineRules(), MyRuleBook can define rules by adding them when defineRules() is invoked. And in CoRRuleBook, defineRules() is invoked when the rules are run, provided no rules have already been defined.

Building a RuleBook by adding Rules externally

RuleBook<Object> ruleBook = new CoRRuleBook<>();
ruleBook.addRule(RuleBuilder.create()
  .when(facts -> facts.getValue("pet sound").equals("meow"))
  .then(facts -> facts.setValue("pet type", "cat"))
  .build());
ruleBook.addRule(RuleBuilder.create()
  .when(facts -> facts.getValue("pet type").equals("cat"))
  .then(facts -> facts.setValue("leather furniture", false))
  .build());