Rule Engines save the day
Posted On August 30, 2007 by Geeta Priya filed under Internet
The problem
* Have you developed/seen business logic code with so many nested if statements that actually looked like a nest?
* Have you spent sleepless nights debugging when you modified one of those ‘if’ statements and found that it screwed up the next if statement?
* Ever wondered how do others implement such things?
Then read on; this article is exactly for you.
If our logic requires triggering different business actions based on many conditions (rules), then implementing such logic in the code becomes a pain. Understanding the code becomes even more painful and it will be a nightmare for people maintaining such code.
In addition, if the business rules are changing frequently, then incorporating these quick changes within the stiff deadlines becomes nearly impossible. We would ideally like to keep these changing rules out of our code. Another reason for this separation is that business people know the rules properly and it would be better if they were allowed to write the rules rather than the developers. Rule engines achieve separation of the rules from the code and make it easier to maintain the code.
What are rule engines and how do they solve my problem?
Rule engines are specialized applications that read a set of rules from external sources (known as rule database or knowledge base); identify the correct rule(s) based on input conditions and execute the corresponding action(s). Rule engines are a great way to collect complex decision-making logic and work with data too large for humans to effectively use.
Rule engines separate the source code from the rule database. Hence, the code does not have to change if there are any changes in the rules. The code looks much neater, simpler to understand and easier to maintain. Business people own the rules while developers own the code.
Case Study
OK; enough of theory. Let us look at some practical usage of rule engines and how they solve our problems.
Let us take one of scenarios in the telecom domain where we want to implement a component that determines whether a customer is eligible to register with the telecom operator. The decision would be based on several factors and is expected to alter frequently.
Just to give you an idea, the decision would be based on the following input conditions,
1. The front-end channel the customer is using, i.e. web-based or through Customer Service Representatives
2. Customer’s scheme, i.e. Monthly Rental (MR) or Pre-paid (PP)
3. Customer status, i.e. New or Existing
4. Response from External Credit History checking authorities about the customer (NCHC and ECHC)
5. Response from systems checking customer details against fraud profiles (PC)
6. Response from Address Verification systems against blacklisted addresses etc (AV)
To complicate the matters, some conditions could be ignored if some of the pre-conditions are met. E.g. If the response from External Credit history check entities is to “DECLINE”, then customer must be declined irrespective of responses from other systems.
Let us see if we implement the above logic in the code itself, how it looks
| .................................................................................................................................................. else if (request.getCreditCheckResp(“DEC”)) { |
The developers will go crazy seeing this code. Clearly the above code is unrealistic, but it shows the complexity.
The next thing we might think is, we will store all the possible values in a database table like the following,
| Channel | CustScheme | CustStatus | NCHC | PC | EC | AC | FinalDecision |
| WEB | MR | NEW | ACC | ACC |
| ACC | ACCEPT |
| WEB | MR | NEW | ACC | DEC |
| ACC | REFER |
| WEB | MR | NEW | DEC |
|
|
| DECLINE |
The above might look like a perfect solution as we can get the final decision in one wonderful SQL query. But there is a problem.
Consider that the input data contains the following responses,
* “DEC” from NCHC system
* “ACC” from PC system
* “ACC” from AC system
The SQL query will not fetch any results with the above data in the tables. For the query to work, we will have to add all the combinations of rules even if we know that “DEC” from NCHC system is sufficient to arrive at a final decision (As told previously, if response from Credit History Check system is ‘DEC’, the customer should be declined irrespective of responses from other systems). Though the solution is better, adding all the worthless data into the above rule table seems pointless. Is there some way we can avoid this?
The answer is yes; rule engines come to our help.
There are many open source Java rule engines. We have chosen ‘Drools’ as our rule engine because it supports rule specification in an excel sheet apart from many other advantages.
The following is the rule specification spreadsheet,
| Type of Decision Request | Channel | Customer Scheme | Customer Type | NCHC | EC | PC | AC | ECHC | Final Decision |
| New MR Customer Check From Web channel | WEB | MR | NEW | ACC |
| ACC | ACC |
| ACCEPT |
| New MR Customer Check From Web channel | WEB | MR | NEW | DEC |
|
|
|
| DECLINE |
| New MR Customer Check From Web channel | WEB | MR | NEW | ACC |
|
| REF |
| REFER |
| New MR Customer Check From Web channel | WEB | MR | EXISTING |
| ACC | ACC | ACC | ACC | ACCEPT |
| New PP Customer Check From Web channel | WEB | PP | NEW |
|
| ACC | DEC |
| REFER |
As can be seen, Business people could easily add the rules to this spreadsheet document. This excel sheet will contain additional information that is relevant to developer and is hidden to the business user.

The code using the rule engine APIs is as follows,
| private RuleBase _ruleBase; private void loadRuleBase() getResourceAsStream("Rule-Decision-Table.xls"); _ruleBase = DecisionTableLoader.loadFromInputStream(stream); } private void executeRules(DecisionRequest req, DecisionResponse resp) WorkingMemory engine = _ruleBase.newWorkingMemory(); engine.assertObject(req); } public static void main(String[] args) throws Exception { // Print the decision stored in the request object by Rule engine |
Given the above excel sheet, Drools reads the rules and executes them according to input conditions (data). All the developers have to do is populate the Request object with the input parameters, invoke Drools API to execute the rules and retrieve the output parameters from the Response object.
The above solution is much neater, simple to understand and implement. It clearly separates the roles of Business analyst and developer, hence reduces considerable amount of time in development and testing of the applications.
Advantages of Drools
- Drools is completely open-source and freely downloadable from the Internet. It uses very liberal ASL/BSD/MIT-esque license.
- Drools conforms to JSR-94 (Rule Engine API) specification
- Drools rule APIs are easier to use
- Drools provides very good documentation
- Drools rule specification language is fairly easy and flexible compared to other rule engines
- Drools supports rule specification in Excel Spreadsheets
- Drools’s performance is excellent
- Commercial support available
- Supports multiple semantic modules Java, Python, Groovy and C#
References:
* Why Use Rules
http://drools.codehaus.org/Why+Use+Rules
* Some Guidelines For Deciding Whether To Use A Rules Engine
http://www.jessrules.com/jess/guidelines.shtml
* Drools site (v3.0)
http://labs.jboss.com/portal/jbossrules
