Modifying code due to business logic changes is a never ending process. In this entry I discuss the merit's of using a math parser to dynamically calculate business logic at run time. This allows for quicker updates and flexible code. I use a real world example of a coupon component that I added to an online shopping cart.
What's a Math Parser
A math parser is simply a group of functions that you can use in your code to parse mathematical expressions. I shouldn't say simple because these libraries are fast and capable of complex calculations. In my case I am just interested in algaebraic functions (or math you would use in business). They still fit the bill perfectly.
I have been wanting to test a math parser to define and execute business logic for some time now. I finally had a chance when I client had requested some coupon functionality to be added to an online shopping cart.
Where Can I Get One
So the first step was to find a free math parser I could use in .Net. This was harder then I expected as there were no FOSS math parsers available. muParser was what I was looking for, but no .Net version.
I eventually found a inexpensive parser ($19.95) that included the source. I downloaded the demo, ran some tests, and found a winner (bcParser.NET).
So Now What
Here is how I used the math parser in the coupon component I did for my client. First off, let me give you a brief overview of basic functionality. The customer would be at the shopping cart page and would have a text box to enter a special coupon code. Once applied this coupon would discount the sub total on the shopping cart.
Here is a simple object for a coupon:
The three values above would be entered by the store admin for each coupon. The coupon code is the code the end user would enter to acitvate the coupon. The parserApply will contain the formala to determine when to apply the coupon. Now these formulas will be standard alegabraic functions as shown below but the really aren't useful unless you introduce optional variables that can be used in the formula. Some common ones would be the item category, item sku, an item total.
Here is an example:
1) A coupon for $5 off $10 or more in CD's:

coupon.parserApply.formula = "(varItemCategory = 5) and (varItemTotal> 10)"; //5 is the item category for CD's and the item total must be greater then $10.

coupon.parserApply.CreateVar("varItemCategory", 5 , null); //5 is the item category of an item in the cart

coupon.parserApply.CreateVar("varItemTotal ", 20 , null); //20 is the item total (item price * qty)

coupon.parserApply.Evaluate(); //this will evaluate to true because the item in the cart is a CD and it's total is> 10


//now calculate the item discount if the coupon should be applied

if (coupon.parserApply.Value> 0)

{

coupon.parserDiscountCalculation.formula = "varItemTotal  5"; //subtract $5

coupon.parserDiscountCalculation.CreateVar("varItemTotal ", 20 , null); //the item total

coupon.parserDiscountCalculation.Evaluate(); // the customer's item will be discounted to $15

itemTotal = coupon.parserDiscountCalculation.Value;

}
So at this point you should be seeing that there is a lot of flexibility in the code. If the client wants to change the logic, it is simply a matter of updating the above formulas in the database. No code changes needed.
The coupon component that I put in place is obviously a little more detailed. As of date, it is working well and the client is very happy with the functionality.
Let me know if you have any questions or comments.
Tue, Nov 28, 2006
Tech Tips