Saturday, October 08, 2005

Rules Engines in Java for your business processes

I'm writing a large application that at some point needs to deal with customisable behaviour. I had intended to use a custom package with standard Java classes that people can customise at will. The interface declaration basically exists and then the implementation of verifiers and state changes and "rules" will be left up to the person that is trying to use the system.

At the moment I am in a bit of a doubt between using a rule engine like "Drools" or continue with what I have. Obviously, the benefit of Java classes is that the compilation is more pedantic and there is a better framework for unit testing. At the other side, actually "changing" business rules might be easier and more fun if there are separate 'files' on a file-system somewhere that are loaded by the application at runtime.

I am considering some details when thinking about this in writing a pre-parser for Drools to make using Drools more accessible. There are a couple of disadvantages that I would like to get rid of:

- Having to know Java import statements
- Uncertainty about order in execution if configuration is messed up ( in direct code this is clearer ).
- Dealing with XML code

If you have a business and you grant a discount voucher of $20 when somebody buys at least 3 books for a minimum value of $100 and the customer has 4 children, how would you express this? This is a question of pre-conditions and post-conditions. In Drools it is very easy for a programmer to express, but a business analyst may have more difficulties finding all the right Java classes to include, order of execution, etc. It would be interesting to see exactly how 'much' it is possible to ditch SQL and 'plumbing' code by employing a rules engine in combination with Hibernate... Hibernate can already auto-generate database schemas based on a mapping file. Would it be possible to auto-generate a mapping file too based on another descriptor file that describes an object and its constraints in real-life ( must have address, must have email, has collection of contacts, has collection of items, has shopping cart, etc...? )

To meet some of the short-comings of rule-based systems, merge it with the idea of a petri-net. A petri-net can be used to 'fire' a rule, action or process when pre-conditions are met. The benefit of petri-nets is that it controls concurrency and execution order and knows about required pre-conditions, things that I think are quite difficult when using a rule-engine stand-alone. Add some time-outs in the net and you've got a framework of execution that is better suited to a business process. This framework could be added to an EJB container even, if one wishes... But what is the use of EJB's if we've got a rules engine? :)

A programmer may also add 'resources' with input parameters to this system that could be EJB's, but not necessarily (and would the EJB use a different instance of a rule-engine? ). For instance, a credit-check system could be a particular resource that an analyst might like to use. Then a business person, when creating a new system, could think of launching a pre-configured standard container, load a new set of business rules on it and start an input connector for new data.

The process generated should become a re-usable sub-process with the inputs and outputs declared, more or less like a white/black-box. This supports the idea of multi-level application overviews. Detail is only important when you need to know it. Dependency resolutions here should allow someone to manage changes. Software development than doesn't really need to think about NullPointers in plumbing code so much. I hope it would eliminate a lot of plumbing that is required nowadays.

Summarized:

A rules engine instance is loaded with a business process. This uses files that can be changed easily later. A petri-net is used to control execution, dependency of other information, process concurrency and time-outs. An analyst creates a new Entity. Based on the description of that entity, a Java class file is generated, a mapping file for Hibernate is generated and a full database schema is generated based on all these entities together ( relationships are declared within the declaration ). The only thing that is still necessary is plumbing code between the 'model' layer and some user interface. Some parts there can also be auto-generated ( Struts Forms <-> data objects for instance ).

Interesting concept and idea! Let me know if you wish to do anything with this, I'd be glad to assist!

No comments: