Rulebook
100% Java, Lambda Enabled, Lightweight Rules Engine with a Simple and Intuitive DSL
Install / Use
/learn @deliveredtechnologies/RulebookREADME
RuleBook <img src="https://github.com/Clayton7510/RuleBook/blob/master/LambdaBook.png" height="100" align="left"/>
» A Simple & Intuitive Rules Abstraction for Java <br/><sub> 100% Java · Lambda Enabled · Simple, Intuitive DSL · Lightweight </sub>
Why RuleBook?
RuleBook rules are built in the way that Java developers think: Java code. And they are executed in the way that programmers expect: In order. RuleBook also allows you to specify rules using an easy to use Lambda enabled Domain Specific Language or using POJOs that you define!
Tired of classes filled with if/then/else statements? Need a nice abstraction that allows rules to be easily specified in a way that decouples them from each other? Want to write rules the same way that you write the rest of your code [in Java]? RuleBook just might be the rules abstraction you've been waiting for!
<sub>Got questions? Here are answers to Frequently Asked Questions!<sub>
<sub>Still not finding what you are looking for? Try the Wiki!</sub>
Contents
- 1 Getting RuleBook
- 2 Using RuleBook
- 3 The RuleBook Domain Specific Language
- 4 POJO Rules
- 5 Using RuleBook with Spring
- 6 How to Contribute
1 Getting RuleBook
1.1 Building RuleBook
git clone https://github.com/Clayton7510/RuleBook.git
cd RuleBook
./gradlew build
1.2 Maven Central Releases
1.3 Latest Sonatype SNAPSHOT (Development) Release
1.4 Adding RuleBook to Your Maven Project
Add the code below to your pom.xml
<dependency>
<groupId>com.deliveredtechnologies</groupId>
<artifactId>rulebook-core</artifactId>
<version>0.12</version>
</dependency>
1.5 Adding RuleBook to Your Gradle Project
Add the code below to your build.gradle
compile 'com.deliveredtechnologies:rulebook-core:0.12'
<sub>[Top]</sub>
2 Using RuleBook
2.1 A HelloWorld Example
RuleBook ruleBook = RuleBookBuilder.create()
.addRule(rule -> rule.withNoSpecifiedFactType()
.then(f -> System.out.print("Hello "))
.then(f -> System.out.println("World")))
.build();
...or use 2 rules
RuleBook ruleBook = RuleBookBuilder.create()
.addRule(rule -> rule.withNoSpecifiedFactType().then(f -> System.out.print("Hello ")))
.addRule(rule -> rule.withNoSpecifiedFactType().then(f -> System.out.println("World")))
.build();
now, run it!
ruleBook.run(new FactMap());
2.2 The Above Example Using Facts
RuleBook ruleBook = RuleBookBuilder.create()
.addRule(rule -> rule.withFactType(String.class)
.when(f -> f.containsKey("hello"))
.using("hello")
.then(System.out::print))
.addRule(rule -> rule.withFactType(String.class)
.when(f -> f.containsKey("world"))
.using("world")
.then(System.out::println))
.build();
..or it could be a single rule
RuleBook ruleBook = RuleBookBuilder.create()
.addRule(rule -> rule.withFactType(String.class)
.when(f -> f.containsKey("hello") && f.containsKey("world"))
.using("hello").then(System.out::print)
.using("world").then(System.out::println))
.build();
now, run it!
NameValueReferableMap factMap = new FactMap();
factMap.setValue("hello", "Hello ");
factMap.setValue("world", " World");
ruleBook.run(factMap);
2.3 A [Slightly] More Complex Scenario
MegaBank issues home loans. If an applicant's credit score is less than 600 then they must pay 4x the current rate. If an applicant’s credit score is between 600, but less than 700, then they must pay a an additional point on top of their rate. If an applicant’s credit score is at least 700 and they have at least $25,000 cash on hand, then they get a quarter point reduction on their rate. If an applicant is a first time home buyer then they get a 20% reduction on their calculated rate after adjustments are made based on credit score (note: first time home buyer discount is only available for applicants with a 600 credit score or greater).
public class ApplicantBean {
private int creditScore;
private double cashOnHand;
private boolean firstTimeHomeBuyer;
public ApplicantBean(int creditScore, double cashOnHand, boolean firstTimeHomeBuyer) {
this.creditScore = creditScore;
this.cashOnHand = cashOnHand;
this.firstTimeHomeBuyer = firstTimeHomeBuyer;
}
public int getCreditScore() {
return creditScore;
}
public void setCreditScore(int creditScore) {
this.creditScore = creditScore;
}
public double getCashOnHand() {
return cashOnHand;
}
public void setCashOnHand(double cashOnHand) {
this.cashOnHand = cashOnHand;
}
public boolean isFirstTimeHomeBuyer() {
return firstTimeHomeBuyer;
}
public void setFirstTimeHomeBuyer(boolean firstTimeHomeBuyer) {
this.firstTimeHomeBuyer = firstTimeHomeBuyer;
}
}
public class HomeLoanRateRuleBook extends CoRRuleBook<Double> {
@Override
public void defineRules() {
//credit score under 600 gets a 4x rate increase
addRule(RuleBuilder.create().withFactType(ApplicantBean.class).withResultType(Double.class)
.when(facts -> facts.getOne().getCreditScore() < 600)
.then((facts, result) -> result.setValue(result.getValue() * 4))
.stop()
.build());
//credit score between 600 and 700 pays a 1 point increase
addRule(RuleBuilder.create().withFactType(ApplicantBean.class).withResultType(Double.class)
.when(facts -> facts.getOne().getCreditScore() < 700)
.then((facts, result) -> result.setValue(result.getValue() + 1))
.build());
//credit score is 700 and they have at least $25,000 cash on hand
addRule(RuleBuilder.create().withFactT
