Externalizing Application Logic: Business Rules Approach

Posted on Posted in Custom Programming, Java, Stories

Externalizing Application Logic: Business Rules Approach

Enterprise applications usually consists of multiple layers. Primarily presentation layer, business logic layer and persistence layer. The business logic layer is considered the heart among these layers, and this is where all processes and decisions take place. Requirements for this layer also changes more often than the rest of the application. As requirements continues to change, it is very easy for the code in this layer to end up tangled in a situation known as “spaghetti code”, lots of nested if-else conditions, and as new conditions are added, readability suffers. Moreover, to change the behavior of the system, a recompile and rebuild must be done.

This post aims to introduce the Business Rules Approach, c where rules, decisions and processes are used by, but does not have to be embedded in business process management systems. You’ll be introduced to this methodology through the use of a business rule engine – JBoss Drools Expert, part of JBoss’ Business Logic Integration Platform.

What are Business Rules?

A business rule is simply a statement that defines or constrains some aspects of the business. Business rules always resolves to either true or false. Business rule can also be defined as an abstraction of the policies and practices of a business organization.

Example:

  • A customer can have several reservations but only one car can be rented at a time. (Car Rental)
  • When a registration is coming from a country listed in the banned country list, reject the registration. (PTC Site Registration)

What is a Rule Engine?

A business rule engine is the heart of the technology behind the Business Rules Approach. It is a system that evaluates and executes one or more business rules in a runtime production system against known facts (domain models).

Why use a Rule Engine?

  • Logic and Data Separation – Your data is in your domain objects, the logic is in the rules.
  • Speed and Scalability – business rules engine uses algorithms design to efficiently match rule patterns to your domain objects, for example the Rete Algorithm as used in Drools Expert. Also in terms of scalability, rules can be shared in different systems allowing us to create or integrate sub-systems that uses some of the rules used by other sub-systems.
  • Centralization of Knowledge – since logic are externalized in the form of rules, there is only a single source of truth, and that is your repository of rules / knowledge (a knowledge base).
  • Explanation Facility – Rule systems effectively provide an “explanation facility” by being able to log the decisions made by the rule engine along with why the decisions were made.
  • Understandable Rules – in Drools Expert, rules can be written using DSLs (Domain Specific Languages) allowing non-technical domain experts to write rules which are close to natural language.

Sample Rules

Sample Hello World Rule

Figure 1: An Example Drools Rule File

Hello Message Rule and Goodbye Message Rule. We can read these rules this way:

  • Hello Message Rule – “When the Message object’s status is HELLO, display the message attribute of the Message object and change its message and status to “Goodbye Cruel World” and GOODBYE respectively”.
  • Goodbye Message Rule – “When the Message object’s status is GOODBYE, display the message attribute of the Message object.”

Make Your Applications Rules-Driven

Drools Expert is a sub-project of JBoss Business Logic Integration Platform and this is the business rule engine we’ll be using in this post. To make your applications rules-driven using Drools Expert, you need first to understand the following important concepts:

  1. Facts – facts are simply your domain objects / models. Rules are run against these facts to match conditions declared in the rules with the state of the fact currently being used and this determines the rule / rules to run.
  2. Rule – a rule is a statement that test a condition against a fact and is composed of 3 important sections:
    1. Name – name of the rule
    2. LHS (Condition) – This is the “when” section (see above). This section declares the condition the rule would test.
    3. RHS (Consequence / Action – This is the “then” section (see above). This section declares the consequence or the action to be performed when the condition declared in the “when” section is met.
  3. Knowledge Base – a repository of rule / knowledge
  4. Knowledge Session – a session is an established interaction between your application and the rules engine. A session is created from a KnowledgeBase and can be either Stateless or Stateful. The application uses the established session to run the engine against the inserted facts.

Sample Code:

package com.ideyatech.drools;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatelessKnowledgeSession;

import com.ideyatech.drools.bean.Message;

public class Main {

	public static void main(String[] args) {
		final KnowledgeBase knowledgeBase =
			createKnowledgeBase();
		final StatelessKnowledgeSession session =
			knowledgeBase.newStatelessKnowledgeSession();

		try {
			final Message message = new Message();
			message.setStatus(Message.HELLO);

			session.execute(message);
		}catch (Throwable e) {
			e.printStackTrace();
		}
	}

	private static KnowledgeBase createKnowledgeBase() {
		final KnowledgeBuilder builder = createKnowledgeBuilder();
		final KnowledgeBase knowledgeBase = KnowledgeBaseFactory
			.newKnowledgeBase();
		knowledgeBase.addKnowledgePackages(
				builder.getKnowledgePackages());

		return knowledgeBase;
	}

	private static KnowledgeBuilder createKnowledgeBuilder() {
		final KnowledgeBuilder builder =
			KnowledgeBuilderFactory.newKnowledgeBuilder();
		final String rulePath = "com/ideyatech/drools/rule/hello-world-rule.drl";

		builder.add(ResourceFactory.newClassPathResource(
				rulePath), ResourceType.DRL);
		if (builder.hasErrors()) {
			throw new RuntimeException(builder.getErrors().toString());
		}
		return builder;
	}
}

Code Explanation:

  • The code above contains two helper methods: createKnowledgeBuilder() and createKnowledgeBase().
  • The createKnowledgeBuilder() method creates an instance of KnowledgeBuilder which is responsible for taking source files such as .drl (Drools Rule) files and turning them into a KnowledgePackage of rule and process definitions which a KnowledgeBase can consume.
    • In this method we added to the KnowledgeBuilder the rule file “hello-world-rule.drl” which is a ClassPath resource. Take note that rules can also obtained as a File resource or a URL resource.
  • The createKnowledgeBase() method creates an instance of KnowledgeBase which is a repository of all the application’s knowledge definitions. This method uses the createKnowledgeBuilder() and gets all knowledge packages from the created KnowledgeBuilder to be used by the created KnowledgeBase.
  • In the main method after creating our KnowledgeBase, we then created a StatelessSession and then asked the created session to execute all rules against the Message object with a status Hello.

When we run this code, this produces the following result:

Sample Code Result

Human-Readable Rules using DSL

In Drools, rules can also be written in a syntax which is close to natural language (English for example). This allows non-technical domain experts to author rules using plain English statements and a few Drools rule syntax which doesn’t require advanced technical knowledge to understand. The example below shows a simple rule written in DSL format.

Sample DSL Rule

Figure 2: DSL File

Sample DSLR File

Figure 3: DSLR File

In the above figures, we have 2 files; a DSL and a DSLR file. The DSL file contains the mapping of the conditions and consequences used in the DSLR file. For example, the DSL condition “There is a customer with firstName {name}” is mapped to “$customer : Customer(firstName == {name})”. This mapping / translation simply tells the engine how to interpret the rule written in the DSLR file.

Conclusion

Truly, by using a business rule engine and allowing business rules to drive our applications, we can increase our development agility, improve software maintainability, and allow us to deal much easier with evolving requirement complexity. However, also take note that by introducing business rule engine to your applications, you also add another layer of complexity to your application architecture. Using a business rule engine should be considered when we need to create pluggable systems, expert systems or when the need to handle ever-changing requirements is very high. For application requirements of moderate complexity, the standard approach of embedding logic through imperative programming language may suffice.

References:

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.