[jboss-svn-commits] JBL Code SVN: r15668 - labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Oct 8 20:22:43 EDT 2007
Author: mark.proctor at jboss.com
Date: 2007-10-08 20:22:43 -0400 (Mon, 08 Oct 2007)
New Revision: 15668
Modified:
labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml
Log:
JBRULES-1257 Add Banking Example from John Dunning
Modified: labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml
===================================================================
--- labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml 2007-10-08 23:24:51 UTC (rev 15667)
+++ labs/jbossrules/trunk/documentation/manual/en/Chapter-Examples/Section-Examples.xml 2007-10-09 00:22:43 UTC (rev 15668)
@@ -664,6 +664,12 @@
<section>
<title>Banking Tutorial</title>
+ <programlisting><emphasis role="bold">Name:</emphasis> BankingTutorial
+<emphasis role="bold">Main class:</emphasis> org.drools.tutorials.banking.*
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> org.drools.tutorials.banking.*
+<emphasis role="bold">Objective:</emphasis> tutorial that builds up knowledge of pattern matching, basic sorting and calculation rules.</programlisting>
+
<para>This tutorial will demonstrate the process of developing a complete
personal banking application that will handle credits, debits, currencies
and that will use a set of design patterns that have been created for the
@@ -672,10 +678,15 @@
functionality, and will instead extend and inject where
appropriate.</para>
- <para></para>
+ <para>The RuleRunner class is a simple harness to execute one or more drls
+ against a set of data. It compiles the Packages and creates the RuleBase
+ for each execution, this allows us to easy execute each scenario and see
+ the outputs. In reality this is not a good solution for a production
+ system where the RuleBase should be built just once and cached, but for
+ the purposes of this tutorial it shall suffice.</para>
<example>
- <title>RuleRunner</title>
+ <title>Banking Tutorial : RuleRunner</title>
<programlisting>public class RuleRunner {
@@ -709,8 +720,11 @@
}</programlisting>
</example>
+ <para>This is our first Example1.java class it loads and executes a single
+ drl file "Example.drl" but inserts no data.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Java Example1</title>
<programlisting>public class Example1 {
public static void main(String[] args) throws Exception {
@@ -720,8 +734,12 @@
}</programlisting>
</example>
+ <para>And this is the first simple rule to execute. It has a single "eval"
+ condition that will alway be true, thus this rul will always match and
+ fire.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Rule Example1</title>
<programlisting>rule "Rule 01"
when
@@ -731,9 +749,22 @@
endh</programlisting>
</example>
+ <para>The output for the rule is below, the rule matches and executes the
+ single print statement.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Output Example1</title>
+ <programlisting>Loading file: Example1.drl
+Rule 01 Works</programlisting>
+ </example>
+
+ <para>The next step is to assert some simple facts and print them out.
+ </para>
+
+ <example>
+ <title>Banking Tutorial : Java Example2</title>
+
<programlisting>public class Example2 {
public static void main(String[] args) throws Exception {
Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
@@ -747,8 +778,17 @@
}</programlisting>
</example>
+ <para>This doesn’t use any specific facts but instead asserts a set of
+ java.lang.Integer’s. This is not considered "best practice" as a number of
+ a collection is not a fact, it is not a thing. A Bank acount has a number,
+ its balance, thus the Account is the fact; but to get started asserting
+ Integers shall suffice for demonstration purposes as the complexity is
+ built up.</para>
+
+ <para>Now we will create a simple rule to print out these numbers.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Rule Example2</title>
<programlisting>rule "Rule 02"
when
@@ -758,9 +798,39 @@
end</programlisting>
</example>
+ <para>Once again, this rule does nothing special. It identifies any facts
+ that are Numbers and prints out the values. Notice the user of interfaces
+ here, we inserted Integers but the pattern matching engine is able to
+ match the interfaces and super classes of the asserted objects.</para>
+
+ <para>The output shows the drl being loaded, the facts inserted and then
+ the matched and fired rules. We can see that each inserted number is
+ matched and fired and thus printed.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Output Example2</title>
+ <programlisting>Loading file: Example2.drl
+Inserting fact: 3
+Inserting fact: 1
+Inserting fact: 4
+Inserting fact: 1
+Inserting fact: 5
+Number found with value: 5
+Number found with value: 1
+Number found with value: 4
+Number found with value: 1
+Number found with value: 3
+</programlisting>
+ </example>
+
+ <para>here are probably a hundred and one better ways to sort numbers; but
+ we will need to apply some cashflows in date order when we start looking
+ at banking rules so let’s look at a simple rule based example.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example3</title>
+
<programlisting>public class Example3 {
public static void main(String[] args) throws Exception {
Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
@@ -774,8 +844,11 @@
}</programlisting>
</example>
+ <para>Again we insert our Integers as before, this time the rule is
+ slightly different:</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Rule Example3</title>
<programlisting>rule "Rule 03"
when
@@ -787,9 +860,39 @@
end</programlisting>
</example>
+ <para>The first line of the rules identifies a Number and extracts the
+ value. The second line ensures that there does not exist a smaller number
+ than the one found. By executing this rule, we might expect to find only
+ one number - the smallest in the set. However, the retraction of the
+ number after it has been printed, means that the smallest number has been
+ removed, revealing the next smallest number, and so on. </para>
+
+ <para>So, the output we generate is, notice the numbers are now sorted
+ numerically.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Output Example3</title>
+ <programlisting>Loading file: Example3.drl
+Inserting fact: 3
+Inserting fact: 1
+Inserting fact: 4
+Inserting fact: 1
+Inserting fact: 5
+Number found with value: 1
+Number found with value: 1
+Number found with value: 3
+Number found with value: 4
+Number found with value: 5
+</programlisting>
+ </example>
+
+ <para>Now we want to start moving towards our personal accounting rules.
+ The first step is to create a Cashflow POJO.</para>
+
+ <example>
+ <title>Banking Tutoria : Class Cashflow</title>
+
<programlisting>public class Cashflow {
private Date date;
private double amount;
@@ -803,16 +906,35 @@
this.amount = amount;
}
-..getters/setters here...
+ public Date getDate() {
+ return date;
+ }
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public double getAmount() {
+ return amount;
+ }
+
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+
public String toString() {
return "Cashflow[date=" + date + ",amount=" + amount + "]";
}
}</programlisting>
</example>
+ <para>The Cashflow has two simple attributes, a date and an amount. I have
+ added a toString method to print it and overloaded the constructor to set
+ the values. The Example4 java code inserts 5 Cashflow objecst with varying
+ dates and amounts.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Java Example4</title>
<programlisting>public class Example4 {
public static void main(String[] args) throws Exception {
@@ -830,8 +952,12 @@
}</programlisting>
</example>
+ <para>SimpleDate is a simple class that extends Date and takes a String as
+ input. It allows for pre-formatted Data classes, for convienience. The
+ code is listed below</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Java SimpleDate</title>
<programlisting>public class SimpleDate extends Date {
private static final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
@@ -842,8 +968,11 @@
}</programlisting>
</example>
+ <para>Now, let’s look at rule04.drl to see how we print the sorted
+ Cashflows:</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Rule Example4</title>
<programlisting>rule "Rule 04"
when
@@ -855,9 +984,37 @@
end</programlisting>
</example>
+ <para>Here, we identify a Cashflow and extract the date and the amount. In
+ the second line of the rules we ensure that there is not a Cashflow with
+ an earlier date than the one found. In the consequences, we print the
+ Cashflow that satisfies the rules and then retract it, making way for the
+ next earliest Cashflow. So, the output we generate is:</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Output Example4</title>
+ <programlisting>Loading file: Example4.drl
+Inserting fact: Cashflow[date=Mon Jan 01 00:00:00 GMT 2007,amount=300.0]
+Inserting fact: Cashflow[date=Fri Jan 05 00:00:00 GMT 2007,amount=100.0]
+Inserting fact: Cashflow[date=Thu Jan 11 00:00:00 GMT 2007,amount=500.0]
+Inserting fact: Cashflow[date=Sun Jan 07 00:00:00 GMT 2007,amount=800.0]
+Inserting fact: Cashflow[date=Tue Jan 02 00:00:00 GMT 2007,amount=400.0]
+Cashflow: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Cashflow: Tue Jan 02 00:00:00 GMT 2007 :: 400.0
+Cashflow: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
+Cashflow: Sun Jan 07 00:00:00 GMT 2007 :: 800.0
+Cashflow: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
+</programlisting>
+ </example>
+
+ <para>Here we extend our Cashflow to give a TypedCashflow which can be
+ CREDIT or DEBIT. Ideally, we would just add this to the Cashflow type, but
+ so that we can keep all the examples simple, we will go with the
+ extensions.</para>
+
+ <example>
+ <title>Banking Tutoria : Class TypedCashflow</title>
+
<programlisting>public class TypedCashflow extends Cashflow {
public static final int CREDIT = 0;
public static final int DEBIT = 1;
@@ -889,8 +1046,13 @@
}</programlisting>
</example>
+ <para>There are lots of ways to improve this code, but for the sake of the
+ example this will do.</para>
+
+ <para>Nows lets create the Example5 runner.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Java Example5</title>
<programlisting>public class Example5 {
public static void main(String[] args) throws Exception {
@@ -913,8 +1075,14 @@
}</programlisting>
</example>
+ <para>Here, we simply create a set of Cashflows which are either CREDIT or
+ DEBIT Cashflows and supply them and rule05.drl to the RuleEngine. </para>
+
+ <para>Now, let’s look at rule0 Example5.drl to see how we print the sorted
+ Cashflows:</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Rule Example5</title>
<programlisting>rule "Rule 05"
when
@@ -929,9 +1097,41 @@
end</programlisting>
</example>
+ <para>Here, we identify a Cashflow with a type of CREDIT and extract the
+ date and the amount. In the second line of the rules we ensure that there
+ is not a Cashflow of type CREDIT with an earlier date than the one found.
+ In the consequences, we print the Cashflow that satisfies the rules and
+ then retract it, making way for the next earliest Cashflow of type
+ CREDIT.</para>
+
+ <para>So, the output we generate is</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Output Example5</title>
+ <programlisting>Loading file: Example5.drl
+Inserting fact: TypedCashflow[date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
+Inserting fact: TypedCashflow[date=Fri Jan 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
+Inserting fact: TypedCashflow[date=Thu Jan 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
+Inserting fact: TypedCashflow[date=Sun Jan 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
+Inserting fact: TypedCashflow[date=Tue Jan 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
+Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Credit: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
+Credit: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
+</programlisting>
+ </example>
+
+ <para>Here we are going to process both CREDITs and DEBITs on 2 bank
+ accounts to calculate the account balance. In order to do this, I am going
+ to create two separate Account Objects and inject them into the Cashflows
+ before passing them to the Rule Engine. The reason for this is to provide
+ easy access to the correct Bank Accounts without having to resort to
+ Helper classes. Let’s take a look at the Account class first. This is a
+ simple POJO with an account number and balance:</para>
+
+ <example>
+ <title>Banking Tutoria : Class Account</title>
+
<programlisting>public class Account {
private long accountNo;
private double balance = 0;
@@ -965,8 +1165,11 @@
}</programlisting>
</example>
+ <para>Now let’s extend our TypedCashflow to give AllocatedCashflow
+ (allocated to an account).</para>
+
<example>
- <title></title>
+ <title>Banking Tutoria : Class AllocatedCashflow</title>
<programlisting>public class AllocatedCashflow extends TypedCashflow {
private Account account;
@@ -1000,8 +1203,12 @@
}</programlisting>
</example>
+ <para>Now, let’s java code for Example5 execution. Here we create two
+ Account objects and inject one into each cashflow as appropriate. For
+ simplicity I have simply included them in the constructor.</para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Java Example5</title>
<programlisting>public class Example6 {
public static void main(String[] args) throws Exception {
@@ -1037,8 +1244,11 @@
}</programlisting>
</example>
+ <para>Now, let’s look at rule Example06.drl to see how we apply each
+ cashflow in date order and calculate and print the balance. </para>
+
<example>
- <title></title>
+ <title>Banking Tutorial : Rule Example6</title>
<programlisting>rule "Rule 06 - Credit"
when
@@ -1068,6 +1278,50 @@
retract($cashflow);
end</programlisting>
</example>
+
+ <para>Here, we have separate rules for CREDITs and DEBITs, however we do
+ not specify a type when checking for earlier cashflows. This is so that
+ all cashflows are applied in date order regardless of which type of
+ cashflow type they are. In the rule section we identify the correct
+ account to work with and in the consequences we update it with the
+ cashflow amount.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example6</title>
+
+ <programlisting>Loading file: Example6.drl
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Feb 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Sun Mar 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Wed Feb 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri Mar 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Sun Apr 01 00:00:00 BST 2007,type=Credit,amount=200.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Thu Apr 05 00:00:00 BST 2007,type=Credit,amount=300.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri May 11 00:00:00 BST 2007,type=Credit,amount=700.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon May 07 00:00:00 BST 2007,type=Debit,amount=900.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Wed May 02 00:00:00 BST 2007,type=Debit,amount=100.0]
+Debit: Fri Mar 02 00:00:00 GMT 2007 :: 400.0
+Account: 2 - new balance: -400.0
+Credit: Sun Mar 11 00:00:00 GMT 2007 :: 500.0
+Account: 2 - new balance: 100.0
+Debit: Wed May 02 00:00:00 BST 2007 :: 100.0
+Account: 2 - new balance: 0.0
+Credit: Fri May 11 00:00:00 BST 2007 :: 700.0
+Account: 2 - new balance: 700.0
+Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Account: 1 - new balance: 300.0
+Credit: Mon Feb 05 00:00:00 GMT 2007 :: 100.0
+Account: 1 - new balance: 400.0
+Debit: Wed Feb 07 00:00:00 GMT 2007 :: 800.0
+Account: 1 - new balance: -400.0
+Credit: Sun Apr 01 00:00:00 BST 2007 :: 200.0
+Account: 1 - new balance: -200.0
+Credit: Thu Apr 05 00:00:00 BST 2007 :: 300.0
+Account: 1 - new balance: 100.0
+Debit: Mon May 07 00:00:00 BST 2007 :: 900.0
+Account: 1 - new balance: -800.0
+</programlisting>
+ </example>
</section>
<section>
More information about the jboss-svn-commits
mailing list