Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A simple design pattern to develop a small Rule-Engine

I have a requirement which take lots of rules validated against the java value objects and produces results. (we cant use any rule engine apps in our company, lots of formalities and lots of questions to be answered). So, rather than implementing the rules as ifs' in java code I suggested to implement a small rule engine, Simple and Extensible. Which design pattern to follow?

I have added below a rough xml structure of the rules defined.

  <rule-set>    
    <name>Example1</name>
    <description>Example rules defined</description>

    <beans>
        <bean class="com.example.Customer" alias="cust"/>
        <bean class="com.example.Account" alias="acnt"/>
        <bean class="com.example.Transaction" alias="trans"/>
    </beans>

    <rule name="CustomerInfo" description="This rule validates if all the customer values are present">
        <if lhs="cust.getFirstName" rhs="null" operator="!="/>
        <if lhs="cust.getLastName" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <if lhs="cust.getCountry" rhs="null" operator="!=" logicaloperator="||"/>
        <if lhs="cust.getCity" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <if lhs="cust.getPhone" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <if lhs="cust.getEmail" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <then do="cust.completeFlag" arg1="true"/>
    </rule>

    <rule name="Transaction" description="Transfer the money from one ac to another">
        <if lhs="trans.fromAccount" operator="!=" rhs="null"/>
        <if lhs="trans.toAccount" operator="!=" rhs="null"/>
        <if lhs="trans.fromAccount.balance" operator=">" rhs="trans.getTransaferAmount"/>
        <then do="trans.fromAccount.debit" arg1="trans.getTransaferAmount"/>
        <then do="trans.toAccount.credit" arg1="trans.getTransaferAmount"/>
    </rule>

</rule-set>

like image 935
Vijay Veeraraghavan Avatar asked Nov 25 '10 09:11

Vijay Veeraraghavan


2 Answers

It really depends on the complexity of the rules you are trying to implement. The key idea in declarative programming is that rules are treated as data. So, the simplest way to start is to see if all your rules can be represented as data in a table. For instance, if your rules are of the type if a=10, then b = 7, then you can represent the same in a table and write a generic method that can handle all your cases.

On the other hand, if your rules allow multiple conditions (and/or clauses as well as comparison operators), a table based design will not help.

In that case, you need to specify the grammar for your rules, generate a lexer and a parser. The parser would parse your actual rules into a abstract syntax tree. Once you get to that stage, you can either take that tree and target it to an existing rule engine or your own rule engine that knows how to execute the tree.

like image 166
Sriram Avatar answered Sep 25 '22 23:09

Sriram


I would recommend a Factory Method Pattern. Each rule will have a Factory that can create those rules. I would then encapsulate all these Rule Factories into an Abstract Factory.

Alternatively, you can create a Rule Engine as a Builder (using a Builder Pattern) that allows passing rule sets and construct a rule.

That's what I would do best, but since I don't know the exact requirements of your rule engine that what popped into mind.

Perhaps a Strategy Pattern could help you?

like image 26
Buhake Sindi Avatar answered Sep 26 '22 23:09

Buhake Sindi