A Small Step Towards Simplifying Software Development

Clayton Long
deliveredtechnologies
5 min readFeb 27, 2017
RuleBook Logo

A Simple and Intuitive Approach to Defining Rules in Java

“Everything should be made as simple as possible, but not simpler.” -A. Einstein

My profession is Software Development, specifically Solution Architecture. In a nutshell, that means I ensure that strategic goals get aligned with technical reality — I translate those goals into technical designs that are scalable, maintainable, and inline with Quality of Service (QoS) expectations. That seems like it should involve some kind of technical wizardry filled with complex logic and algorithm alchemy. The reality is that, the best approaches are often the simplest ones. After all, if nobody understands what you are trying to do, then convincing people to do it (and showing people how to do it) becomes much harder than it should be.

So, it should come as no surprise that when I run into problems, I look for simple solutions. Recently, I came across an issue where it seemed like no simple solution was available: business rules were becoming a maintenance problem. So, I decided to write my own Java Rules Engine.

I know what you are thinking. What about Drools? Or even Easy Rules? Believe me, I looked at them. And they were more than what I needed. I had used Drools before, and although it was very powerful, it was not what I would call simple; I needed a simple solution (to my project’s growing mess of tangled if/then/else business rules) that was lightweight, easy to learn and at the same time, powerful. Easy Rules was a close contender, but even it had some bulk and a bit of custom ceremony that my developers would have to take time to learn. Enter RuleBook.

RuleBook started out as just a simple Chain of Responsibility pattern implementation with some syntactic sugar that included lambda and a basic given/when/then Domain Specific Language (DSL). And at its core, that’s what it still is! It does all the things that a rules engine is supposed to do. But it’s easy, with virtually no learning curve (or dependencies). And its DSL supports lambda, so a rule can literally be defined in a single line of code. How’s that for little ceremony!

Drools still has its place. And in some cases, it may be a better tool than RuleBook. But I think in many cases, RuleBook is a better choice (and not just because I wrote it :). RuleBook favors simplicity and predictable ordering of execution above all else, whereas Drools favors flexibility and speed above all else. Certainly, there are cases where you need to write rules in multiple ways or have them execute using the efficiency of the Rete algorithm. But usually execution performance and rule source management are not bigger concerns than easily defining the rules and making them run in a predictable way. More often than not, simplicity and predictability are more important than outright performance; the former(s) are always needed, the latter is rarely needed.

“ Any system with enough rules to need sophisticated algorithms to get good performance probably has too many rules to be understood.” -M. Fowler

The easiest way to define rules in RuleBook is in a RuleBook class.

In the example above, there are two Facts (data passed into rules, which can also reflect state changes) defined and two rules defined using the RuleBook DSL. Since rules are executed in the order in which they are defined, there is no guesswork involved — what you see is what you get and the order that you get it in. It doesn’t get much easier than that.

Using the DSL is my preferred method for quickly defining rules. But if you have a growing library of rules, RuleBook allows you to abstract your rules into separate POJO classes as shown below.

POJO rules use annotations to map methods to RuleBook rules and Facts. But they work exactly the same way. However, instead of defining rules inside of a RuleBook class, rules are defined inside of a package that’s scanned by a RuleBookRunner, which then uses the rules in the package to build a RuleBook.

The example immediately above evaluates loan applicants against rules to determine whether or not they are approved. There are 3 rules that determine loan acceptance: there can be no more than 3 applicants, and if any applicants have less than a 700 credit score, then all applicants must have at least $50,000 in cash on hand. Although this is a relatively simple example, it quickly becomes clear that RuleBook can easily scale up rules in a simple way that keeps rules decoupled from on another.

Finally, as I was creating RuleBook, I noticed that there was a need for rules to distill facts down to a single result. As a consequence, DecisionBook was born. DecisionBook is a special type of RuleBook class that maintains a result separate from its facts (notice how the POJO rule above does that too). And like facts, the result can be read or modified by any rule in the chain, allowing the result to be an aggregate of the actions of every rule in the DecisionBook.

What initially started as a quest for a simple and streamlined Java rules engine, became a GitHub project. And as all the best projects do, it came from a need to solve a recurring problem and to build better [and simpler] software.

Oh, and if you are interested in contributing, please do!

Update: Since this article was first written, additional support for Spring has been added to RuleBook!

--

--

Clayton Long
deliveredtechnologies

Cloud Automation Manager by profession, Programmer in my free time, and lover of anything that makes my life easier.