The OpenRulesTM Tutorials         Home   PREV TOP NEXT User's Guide
Divider

Rule Templates

OpenRules Templates provide a powerful while intuitive mechanism for a compact organization of enterprise-level business rules repositories.  Rule templates allow rule designers to write the rules logic once and use it many times. With rule templates  you may completely hide rules implementation details from business users. OpenRules supports several rule templatization mechanisms from simple rule tables that inherit the exact structure of templates to partial template implementations.  Rule templates are available starting from the OpenRules version 5.0.

Simple Rule Templates  ►top 

Rule templates are regular decision tables that are as structural prototypes for many other rule tables with the same structure but different rules. A simple rule template usually does not have rules at all but only specifies the table structure and implementation details for conditions and actions. Thus, a simple rule template contains the first 5 rows of a regular decision table like in this example:

Rules void defineGreeting(App app, int hour) - Signature with parameters
C1 A1 - Conditions and Actions identifiers
min <= hour && hour <= max

app.greeting = greeting; 

- Java snippets describe condition/action semantics
int min int max String greeting - Parameter types and names
Hour From Hour To Set Greeting - Business names for conditions and actions

We may use this decision table as a template to define different greeting rules for summer and winter time. The actual decision tables will implement (or extend) the template table with particular rules:

Rules summerGreeting template defineGreeting
Hour From Hour To Set Greeting
0 10 Good Morning
11 18 Good Afternoon
19 22 Good Evening
23 24 Good Night

and

Rules winterGreeting template defineGreeting
Hour From Hour To Set Greeting
0 11 Good Morning
12 17 Good Afternoon
18 22 Good Evening
23 24 Good Night

Note that Rules tables "summerGreeting" and "winterGreeting" do not have technical information at all - Java snippets and a signature are defined only once and reside in the template-table "defineGreeting".

Along with the keyword "template" you may use other keywords:

We will refer to these rule tables created based on a template as "template implementations".

Simple templates require that the extended tables should have exactly the same condition and action columns.

Templates with Defaults Rules for Multi-Hit Tables ►top 

Multi-hit decision tables execute all their rules that are satisfied allowing rules overrides. However, when conditions in All specified rules are not satisfied then a multi-hit table usually uses the first(!) rule to specify the default action.  When many single-hit tables are created based on the same rule template, it could be inconvenient to keep the same default rules in all extended tables.  As an alternative you may add the default rules directly to the template. The rules from the template will be executed before the actual rules defined inside the extended tables.

Let's consider an example. You may notice that the rules tables above would not produce any greeting if the parameter "hour" is outside of the interval [0;24].  Let's assume that in this case we want always produce the default greeting "How are you". To do this it is enough to add one default rule directly to the template: 

Rules void defineGreeting(App app, int hour)    
C1 A1    
min <= hour && hour <= max

app.greeting = greeting; 

   
int min int max String greeting    
  How are you   This rule will be added at the beginning of all template implementations. This greeting will be produced if all other rules in the rule tables fail

A template for multi-hit tables could include more than one default rule with different conditions - they all will be added to the template implementation tables at the beginning to execute different default actions.

Templates with Defaults Rules for Single-Hit Tables ►top 

Single-hit decision tables usually end their execution when at least one rules is satisfied. However, when conditions in All specified rules are not satisfied then a single-hit table usually uses the last(!) rule to specify the default action.  When many single-hit tables are created based on the same rule template, it could be inconvenient to keep the same default rules in all template implementations.  As an alternative you may add the default rules directly to the template. The rules from the template will be executed after the actual rules defined inside the template implementations.

Let's consider an example. You may notice that the rules tables above would not produce any greeting if the parameter "hour" is outside of the interval [0;24].  Instead of adding the same error message in both "summer" and "winter" rules, we could do the following:
-
make our "defineGreeting" template a single-hit table by changing a return type from "void" to "String"
- add the default reaction to the error in "hour" directly to the template: 

Rules String defineGreeting(App app, int hour) - Signature now returns String
C1 A1 - Conditions and Actions identifiers
min <= hour && hour <= max

app.greeting = greeting; return greeting;

- "return greeting;" has been added
int min int max String greeting - Parameter types and names
Hour From Hour To Set Greeting - Business names for conditions and actions
  ERROR: Invalid Hour   This rule will be added at the end of all template implementations tables. The error message will be return instead of a greeting when all other rules fail.

A template for single-hit tables could include more than one rule with different conditions - they all will be added at the end of the template implementation tables to execute different default actions.

Partial Template Implementation ►top 

Usually template implementation tables have exactly the same structure as the rule templates they extend. However, sometimes it is more convenient to build your own template implementation using only some conditions and actions from already predefined rule templates. It is especially important when there is a library of rule template for a certain line of business is used to create a concrete rules-based application. How can it be achieved?

The template implementation table uses its second row to specify the names of the used conditions and actions from the template! Let's consider an example. The DebtResearchRules from the standard OpenRules example "Loan Origination" may be used as the following template:

Rules void DebtResearchRules(LoanRequest loan, Customer c)
C1 C2 C3 C4 C5 C6 C7 A1
c.mortgageHolder.equals(YN) c.outsideCreditScore>min &&
c.outsideCreditScore<=max
c.loanHolder.equals(YN) op.compare(c.creditCardBalance,value) op.compare(c.educationLoanBalance,value) contains(rates,c.internalCreditRating) c.internalAnalystOpinion.equals(level) loan.debtResearchResult = level;
out("Debt Research Result:"+level);
String YN int min int max String YN Operator op int value Operator op int value String[] rates String level String level
IF
Mortgage Holder
AND
Outside Credit Score
AND
Loan Holder
AND
Credit Card Balance
AND
Education Loan Balance
AND
Internal Credit Rating
AND
Internal Analyst Opinion
THEN
Debt Research Recommendations
Min Max Oper Value Oper Value

We may create a rule table that implements this template using only conditions C1, C2, C5, C6 and the action A1:

Rules MyDebtResearchRules template DebtResearchRules
C1 C2 C5 C6 A1
IF
Mortgage Holder
AND
Outside Credit Score
AND
Education Loan Balance
AND
Internal Credit Rating
THEN
Debt Research Recommendations
Min Max Oper Value
Yes                   High
No 100 550               High
No 550 900               Mid
No 550 900 > 0           High
No 550 900 <= 0 A B C     High
No 550 900 <= 0 D F       Mid
No 550 900               Low
No 550 900 <= 0           Low
No 550 900 > 0 D F       High
No 550 900 > 0 A B C     Low

The additional second row specifies which conditions and actions from the original template are selected by this rules table. The order of conditions and actions may be different from the one defined in the template - only the names like "C2", "C6", "A1" should be the same in the template and in its implementation. It is more preferable to use unique names for conditions and actions inside templates. It there are duplicate names inside templates the first one (from left to right) will be selected.

Templates with Optional Conditions and Actions ►top 

There is another way to use optional conditions and actions from the templates. If the majority of the template implementations do not use a certain condition from the template, then this condition may be explicitly marked as optional by putting the condition name in the brackets, e.g. "[C3]" or "[Conditon-5]".  In this case it is not necessary to use the second row to specify the selected conditions in the majority of the extended tables.  For example, let's modify the DebtResearchRules template making the conditions C3, C4, and C7 optional:

Rules void DebtResearchRules(LoanRequest loan, Customer c)

C1
 
C2 [C3] [C4] C5 C6 [C7] A1

Now we can implement this template as the following rules table without necessity to name all conditions and action in the second row:

Rules MyDebtResearchRules template DebtResearchRules
IF
Mortgage Holder
AND
Outside Credit Score
AND
Education Loan Balance
AND
Internal Credit Rating
THEN
Debt Research Recommendations
Min Max Oper Value
Yes                   High
No 100 550               High
No 550 900               Mid
No 550 900 > 0           High
No 550 900 <= 0 A B C     High
No 550 900 <= 0 D F       Mid
No 550 900               Low
No 550 900 <= 0           Low
No 550 900 > 0 D F       High
No 550 900 > 0 A B C     Low

However, a template implementation that does want to use optional conditions will have to specify them explicitly using the second row:

Rules MyDebtResearchRules template DebtResearchRules
C1 C2 C3 C4 C5 C6 A1
IF
Mortgage Holder
AND
Outside Credit Score
AND
Loan Holder
AND
Credit Card Balance
AND
Education Loan Balance
AND
Internal Credit Rating
THEN
Debt Research Recommendations
Min Max Oper Value Oper Value
Yes                         High
No 100 550                     High
No 550 900 Yes <= 0               Mid
No 550 900 Yes > 0 > 0           High
No 550 900 Yes > 0 <= 0 A B C     High
No 550 900 Yes > 0 <= 0 D F       Mid
No 550 900 No > 0               Low

Similarly optional actions may be marked as [A1]" or "[Action3]".

       Implementation Notes:

 

Template Benefits  ►top 

While the new rules templatization (or rules inheritance) mechanism is simple and intuitive it brings enormous advantages from the rules management perspective: 

►top

Divider