| The OpenRulesTM Tutorials Home |
|
User's Guide |
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:
implements
implement
extends
extend
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<=maxc.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 HolderAND
Outside Credit ScoreAND
Loan HolderAND
Credit Card BalanceAND
Education Loan BalanceAND
Internal Credit RatingAND
Internal Analyst OpinionTHEN
Debt Research RecommendationsMin 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 HolderAND
Outside Credit ScoreAND
Education Loan BalanceAND
Internal Credit RatingTHEN
Debt Research RecommendationsMin 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