I'm haiving an interesting discussion with an esteemed colleague and would like some additional input...
I need to implement some basic decision table logic in my application. I was looking to use OpenL Tablets which represents decision data in an Excel spreadsheet. I like it, it's easy to set up and maintain and has a small memory and processing footprint. I can add new tables easily and I have some tables with over 100 rows and upto 10 conditions. This data is pretty static and rarely changes.
My colleague does not want to introduce a third party api into the mix and has reservations about being tied to a Microsoft file format.
I see his point but the only way I can see of implementing the decision table via Java is to code a series of ugly if or case statements, which is fine for the smaller tables but would become unmanageable when I get to the bigger tables.
Does anyone have any comments on both sides of the argument. If anyone has any thoughts as to a pattern that could solve my problem in native Java I'd be interested to hear it.
Many thanks for your time.
Hmmm, a completely naive attempt:
public interface Condition<Type T> {
public boolean process(T object);
}
ArrayList row = new ArrayList<Condition>(10);
row.add( new Condition<YourObject>() {
public boolean process(YourObject obj) {
if ( obj.property > 0 ) return true;
else return false;
});
row.add( new Condition<YourObject>() {
public boolean process(YourObject obj) {
if ( obj.property2 == 100 ) return true;
else return false;
});
Then you would iterate:
for ( Condition<YourObject> cond : row ) {
if ( ! cond.process(yourobj) ) break;
}
A slightly more sophisticated example you could write your decision table in javascript a lot more succinctly, and perhaps use Beanshell to execute the logic. I would have to hit a shell and bang on this a bit before I could post you an example.
Or it's possible if you posted an example someone could come up with some simple Scala routines to do what you want.
EDIT:
So I did a little research and thinking, and for Beanshell you could use something like so:
import bsh.Interpreter;
Interpreter i = new Interpreter(); // Construct an interpreter
YourObject yourObject = new YourObject();
i.set("myObject", yourObject );
// Source an external script file
i.source("somefile.bsh");
And somefile.bsh might look like this:
var rules = new Array();
rules.push( function(var) {
if ( var.getProperty() == 0 ) return true;
else return false;
});
rules.push( function(var) {
if ( var.getProperty() < 1000 ) return true;
else return false;
});
... more rules ...
for ( var func in rules ) {
if ( !func( myObject ) ) break;
}
This would give you more flexibility to change the rules than recompiling Java source.
You would have to add another array to either of these solutions to get your 100 source "rows"