[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