I’ve always gone into a lot of detail regarding specific points of the rule engine, but I feel this is a topic which needs to be covered more. So this post is oriented to people who might just be getting started with the concept of rules and are still in doubt. I will try to explain some of the advantages of using business rules and rule engines in a way that, oddly enough, I haven’t found online yet.
What is a rule?
If you got as far as reaching this blog, you probably already have an idea of what a rule is. The most primal explanation we can give is “something that looks like this”:
when a condition is found to be true
then a consequence is executed
And that’s about it. Add as much syntax sugar as you want on top of it, but a rule will still have that basic structure underneath it all. I still remember the first question that rose to the top of my head when they explained what a rule was: How is this any better than writing code? It took me a while to figure it out, but I’ll try to make it easier for you
Let’s begin by explaining the reason of such a simple structure. It’s based on an Artificial Intelligence principle, where a specific structure of code can be represented as data, in a structure similar to the one shown in the following diagram:
Why would we want to represent our code as data? Because manipulating that data makes a system able to change what it is doing, and it is one of the pillars of machine learning. Having the execution code as data means that we can change the data and make the system behave in a different way without having to restart any component. But that is not even the beginning of why rules are something useful:
It is not what one rule can do, but what many together can do
If we think of an extremely simple case, where maybe we have one or two rules to define a scenario, we can definitely think of a simpler way of doing the same scenario using nothing but Java. The power of rules doesn’t reside in the possibility of explaining simple scenarios, but quite the contrary. It lies on explaining complex scenarios in a very simple and performing way. It divides a problem in the most atomic components: each individual decision we could take, together with the minimal information we need to take that decision. No rule should extend beyond that complexity.
Rules don’t know each other
This is a principle most rule engines abide: Rules are independent. Each rule doesn’t know if another rule even exists. All they share is the information about the state of the world. This information is shared, and some rule engines (drools included) allows for rules to modify this information, in order for other rules to be activated. This process of activating other rules by changes in the information of the state of the world (called working memory) is called inference.
Because of this mechanism, rules don’t need to be too complex to describe a complex scenario: a complex rule can be divided into simpler rules that infer parts of information of a complex scenario and feed it to the working memory, and other rules might depend on that data to get activated. Which leads to the next item regarding how to manage complex, ever-growing situations
Scenario becomes more complex? Just add more rules
This is how you should manage complex scenarios. You don’t have to worry about having a very complex list of commands to evaluate each condition on a complex decision. All you need is to keep creating atomic rules, until you have covered all the different cases. Rules become the epitome of decoupling software: Each rule should just worry about understanding a very small and basic concept from the information it can gather from the state of the world
Letting the rule engine do its job
Rules should remain that simple because it is the rule engine that will manage the complexity for us. Whenever we need to detect many similar conditions, the rule engine will create a performing way of evaluating those conditions as fast as possible, through the RETE (in drools 5) and PRHEAK (in drools 6) algorithms. They will do the heavy lifting. It’s something that we have seen before:
If you’re as old as I am, you might have been there when development teams started going from compiled code (like C or C++) to interpreted code (like Java). I didn’t like it that much at first: I needed more resources to run the programs I made, I had to learn new APIs, everything was a class now… it just wasn’t my cup of tea, at least until I got the hang of it. The thing was that, in order to write good Java code, I needed to follow very different standards from those to write good C code. I didn’t need to create fancy optimizations in our code because those optimizations were going to be done by the VM. And eventually, simpler code became more efficient than complex code hacks we brought with us from C, mainly because the VM optimizations were doing it so much better than us.
And in a sense, a rule engine does the same thing. It will take all our rules and transform them into something that can run in the most efficient way to find all the matches to our rules. In a system with many rules, the code to evaluate the conditions will be far quicker than the optimizations we might add to a batch processing on a code block.
And that is pretty similar when talking about rule engines and rules. Its like the VM and Java code all over again. Someone will be able to do a better job than you at optimizing simple scenarios, so we shouldn’t have to worry about optimizing the code so much as making it clearer.
Fitting more hands in a plate
There is a common saying in engineering: You can’t make 9 mother make one baby in a month. We use it as a clear example of how some tasks cannot be divided any more, and have specific dependencies between each other. The phrase is used to describe situations where you have coupled code, and even if we divide a problem into many different tasks, people will end up touching the same components (and experiencing the expected conflict) when trying to solve two different situations.
One of the greatest advantages of rules is how highly detached they are. This means more people can be editing the rules without stepping in each other toes. The simpler the rules, the less experience needed to edit them. And thanks to human language to rules mappings (like DSLs and Decision Tables), you can have non-technical people defining rules. This means more people can get involved in rule definition, and help extend a system that could be as complex as necessary, and do it in the simplest of ways.