| Sign In/My Account | View Cart |
Give Your Business Logic a Framework with Drools
Pages: 1, 2, 3, 4, 5, 6, 7
Now the folks on the business side are really impressed and are starting to think through the possible options. They've come across a problem with stocks of XYZ Corp and have decided to implement a new rule: Only buy stocks of XYZ Corp if they are less than 10 Euro.
As before, you add the test to our simulator and include the new business rule in our rules file, as per the following listings. First, we add a new method to BusinessRuleTest.java:
/**
* Makes sure the system will buy stocks
* of XYZ corp only if it really cheap
*/
public void testXYZStockBuy() throws Exception{
//Create a Stock with our simulated values
StockOffer testOfferLow = new StockOffer();
StockOffer testOfferHigh = new StockOffer();
testOfferLow.setStockName("XYZ");
testOfferLow.setStockPrice(9);
testOfferLow.setStockQuantity(1000);
testOfferHigh.setStockName("XYZ");
testOfferHigh.setStockPrice(11);
testOfferHigh.setStockQuantity(1000);
//Run the rules on it and test
BusinessLayer.evaluateStockPurchase(
testOfferLow);
assertTrue("YES".equals(
testOfferLow.getRecommendPurchase()));
BusinessLayer.evaluateStockPurchase(
testOfferHigh);
assertTrue("NO".equals(
testOfferHigh.getRecommendPurchase()));
}
Next, we need a new <rule> in
BusinessRules.drl:
<rule name="XYZCorp" salience="-1">
<!-- Parameters we pass to rule -->
<parameter identifier="stockOffer">
<class>StockOffer</class>
</parameter>
<java:condition>
stockOffer.getStockName().equals("XYZ")
</java:condition>
<java:condition>
stockOffer.getRecommendPurchase() == null
</java:condition>
<java:condition>
stockOffer.getStockPrice() > 10
</java:condition>
<!-- What happens when the business
rule is activated -->
<java:consequence>
stockOffer.setRecommendPurchase(
StockOffer.NO);
printStock(stockOffer);
</java:consequence>
</rule>
Note that in the business rules file, after the rule name, we
set our salience to -1 (i.e., the lowest
priority of all of the rules we have specified so far). Most of the
rules in our system conflict, meaning Drools must make some
decision on the order in which to fire rules, given that the
conditions for all of the rules will be met. The default way of
deciding is:
Salience: A value we assign, as per the above
listing.Recency: How many times we have used a rule.Complexity: Specific rules with more complicated values
fire first.LoadOrder: The order in which rules are loaded.If we did not specify the saliency of our rule in this example, what would happen is:
Recommend Buy flag
would be set to No).Recommended Buy flag to yes.This would give a result that we don't want. However, since our example does set the saliency factor, the test and our business rules work as expected.
While most of the time, writing clear rules and setting the saliency will give enough information to Drools for it to choose the proper order in which to fire rules, sometimes we want to change the entire manner in which rule conflicts are resolved. An example of how to change this is given below, where we tell the rule engine to fire the simplest rules first. A word of warning: be careful when changing conflict resolution, as it can fundamentally change the behavior of the rule engine--a lot of problems can be solved first with clear and well-written rules.
//Generate our list of conflict resolvers
ConflictResolver[] conflictResolvers =
new ConflictResolver[] {
SalienceConflictResolver.getInstance(),
RecencyConflictResolver.getInstance(),
SimplicityConflictResolver.getInstance(),
LoadOrderConflictResolver.getInstance()
};
//Wrap this up into one composite resolver
CompositeConflictResolver resolver =
new CompositeConflictResolver(
conflictResolvers);
//Specify this resolver when we load the rules
businessRules = RuleBaseLoader.loadFromUrl(
BusinessLayer.class.getResource(
BUSINESS_RULE_FILE),resolver);
For our simple application, driven by JUnit tests, we don't need to alter the way the Drools resolves rule conflicts. It is useful to know how conflict resolution works, especially when your application grows to meet more complex and demanding requirements.
This article demonstrated a problem that most programmers have had to face: how to put some order on the complexity of business logic. We demonstrated a simple application using Drools as a solution and introduced the notion of rule-based programming, including how these rules are resolved at runtime. Later on, a follow-up article will take these foundations and show how to use them in an enterprise Java application.
Paul Browne , based in Dublin, Ireland, has been consulting in enterprise Java with FirstPartners.net for almost seven years.
Return to ONJava.com.
Showing messages 1 through 15 of 15.
Iter Java Drools
1 10 10
10 0 0
100 10 0
1000 10 0
10000 40 0
100000 161 0
1000000 1572 40
Total 1803 1582
Obj
1 111 20
10 871 10
100 7771 60
1000 78344 261
10000 761312 23655
No , you didn't miss anything - the example(s) were kept very simple for clarity.
For the example you are talking about , you would probably split the Rules into two Sets (.drl files) - one for sell and one for buy.
If your question is more 'how do I model more complex rules , you would either (a) make your preconditions more complex - more conditions to be satisified before the rule fires or (b) Arrange it so that Rule 2 would only fire of a change made to working memory by Rule 1.
The www.drools.org site has a lot of additional information on this subject.
Paul Browne - www.firstpartners.net/rp
I've also been very impressed by the Drools project in general.
I wouldn't see Drools as 'program-in-XML-instead-of-Java' - the underlying approach is very different: With Drools you state what you know to be true , with Java you say exactly what you want done. The Drools approach can lead to more simple code (none of those messy , tangled , if..then statements).
In an 'ideal world' not only could business analysts write rules (if they wanted to) , but other Analysts could use RAD Tools to develop the user interface (the market Visual Basic aimed at). The productivity gain comes from not waiting for a developer to translate requirements into code , with the possibility of making mistakes.
In reality , there will always be requirements that need a Developer (such as writing rules against a Database). As ever , the balance of work between Developer and Analyst will depend on project, organisation and skillsets.
Paul Browne
http://red-piranha.blogspot.com/
The follow up to this article makes the case even clearer in an Enterprise Java setting , with Frameworks (Struts-Drools-Hibernate) combined to remove the need for a lot of repetitive 'infastructure' type code.
The intention is to extract the business rules from the java code , in a format that non-java people , such as Business analysts can understand. As such , the choice of formats would be XML , Database or some sort of text file (as used by Jess.
There are tools such as DRL Assistant (http://www.zymose.com/faq.html) that can hide the XML format for these business users.
Deployment of Drools
More at http://edmblog.fairisaac.com