Over on my blog roll one of the blog sites I like to visit every so often is the Daily WTF. This site essentially takes code samples and say - "OK, what were the people who wrote this thinking?" Let me say up front I've never submitted any code to this site, but since I had a chance today to catch a breath I stopped by and they had an code that involves, what for lack of a better term I would call a design pattern, the rules processor.
Now there are several things that sound great when you talk about a rules processor, and generally the thought process goes something like:
" Wouldn't it be great if instead of writing an application that embedded business logic regarding how to process an order or handle a customer request and then having programmers need to make changes when our process or business rules change;
We could instead have an application that read our business rules out of a database and then ran these rules against the customer database."
As this post on the Daily WTF notes, this is a admirable desire, but unfortunately if you try to build it yourself from scratch - well don't be surprised if you wind up with something similar to what this post is highlighting: http://www.thedailywtf.com/forums/68489/ShowPost.aspx
Let me reiterate - I don't know where that code came from much less did I submit it. However, I disagree with a couple things in that post.
First I think there is value in working to transfer rules out of code if those rules are dynamic. It's that word dynamic that I think people sometimes forget. Will the "number of days" to apply X ever change from being a number? No, so don't make it a rule, put it in code. Will the "maximum number of days" ever change - probably, so make it a 'rule' or at least a setting.
The difference is important because while I can create an engine to look for a generic rule to test for both the fact is the more rules my system needs the more complex the maintenance of those rules becomes and the greater the liklihood that I'll need a specialized employee to maintain those rules, thus defeating the original goal of the rules processor.
Secondly, look at what tools are already available on the market. There are companies that specialize in making and implementing rules engines - consider purchasing one of these existing products. More importantly, when I examine most rules processors what I find is that over time then tend to combine data validation based business rules with workflow based data processing.
Let me explain the what I mean by a difference. A rules engine is applying rules to see if an action or set of data meets the business requirements necessary to accept that data or start an action. A workflow engine takes data which is nominally valid and ensures that it flows to all the appropriate points in your organization or even across organizations, so that the customer's request to result in a desired outcome.
Now in a discussion around requirements these two things can sound very similar. For example "Ensure the order has a maximum number of days duration." sounds very similar to "Ensure the order goes to fulfillment and is processed within X days." However, these two requirements require entirely different approaches, one is focused on getting the correct information, the other is focused on how that data is handled.
Which brings us to Windows Workflow Foundation, similar to BizTalk, this is a technology designed to process your data. If you start trying to take the 'workflow rules' and apply them like definitions to data validation you will find yourself writing some *very* convoluted code. Don't get me wrong both WWF and BizTalk do a certain level of data validation in order to accept an object for processing, but you'll note that validation isn't the same as what they do in their actual workflow process.
So when you are designing your system and the question of 'rules' comes up start thinking about:
- What elements of the system need rules?
- Keep the rules simple, otherwise even if they aren't compiled they'll require a programmer using a custom syntax to maintain.
- Separate rules from workflow.
- Leverage existing products to both speed your development and ensure a standard implementation.