Sunday, July 6, 2008

Externalize Business Rules/Validation to Scripting Language

Goal
Business rules (stored as Ruby/Groovy or Bean Shell) mentioned on the "Object", should be triggered automatically whenever there is an update/modification to its value.The modification/update can be called from UI/ any other external source. Following key driving parameters for design:-

1. Optimal but not lightening performance, that is, the system should not go for sleep when performing the validation

2. There will be bulk insert/update scenarios/use cases, hence special care should be taken for memory leaks.

3. Flexibility

4. Easily maintainable

This page is an attempt to design/solve the control rule evaluation

at server side mainly.


Assumptions

1. Use Ruby 0.9 / 1.0 or Groovy 1.0 / 1.5 or BeanShell 2.0 for writing the control rules. The design should be extensible that is, if some client want to use rule engine or java code.,the impact should be minimum.

2. The framework in which the below mentioned design will be implemented should support

a. Support Dependency Injection at runtime

b. Support Aspect Oriented Programming

3. Store groovy validation as a method inside the groovy class to enable injection of groovy class into java class.This will also avoid any class loading issues.

4. UI should take script in a compiled format.


Design principles

  1. Automatic syntax checking, compilation and loading at runtime. Note scripting language like groovy uses JIT compilation
  1. Lose coupling i.e. validation module at runtime will be injected into the Domain Object whenever there is a change/modification.
  1. Avoid any class loading issue between groovy object & java object.
  1. Changes to the control rules (i.e. groovy scripts) should be refreshed & loaded at runtime.

Tech Stack

1. Using spring 2.5. 2 dynamic scripting support & JEE 1.5 + platform

Usage of Spring Framework dynamic scripting provides out of the box support for the design principles mentioned above without any extra effort in research/coding.


Design

1. Any change in the domain model trigger “Validation”

2. As soon as there is an update operation on the domain model field, on which business rules are specified, "Object Model value validation Aspect” will be triggered, which take all the responsibility of:-

a. Find the correct validation as groovy script

b. Inject the above groovy validation as normal java object into the "Domain Model"& perform required validation


Here is the sequence diagram


Summary

1. Using aspect-oriented approach there is no hard coupling between 1 & 2 mentioned above.

2. Since groovy validation is injected into the java object – "DomainObject", there will be no class loading issues.

3. The above design exploits "Single Responsibility Design Principle" via usage of runtime dependency injection and aspect (hence loosely coupled code) of spring. That is, aspect take up the following responsibility and will be coded at one place:-

a. Find the validation for the "DomainObject"value

b. Inject into the target object i.e. "DomainObject"

c. Call the groovy validation using java reflection API (Method Dispatcher).

4. In spring all beans are singleton and thread safe which will avoid memory leaks. This will ensure very fast performance & response time.