Native Java Solution to Decision Table
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 开发者_StackOverflow中文版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"
1) If your app needs high performance, the naive approach will become slow pretty soon on large tables. For example, OpenL Tablets indexes decision tables in most cases providing constant performance for any table size.
2) Once you start to build on top of the naive approach, you'll see that you need to implement different types of conditions, data parsers for different types etc.
3) OpenL Tablets allows you to use .xls files on any Java-capable platform, it is just a storage format, the library itself is pure Java. And finally, Excel file is one of the most easily converted/exported/imported file formats in the whole Universe.
4) The OpenL Tablets runtime dependency size grew recently due to switching to the latest Apache POI library for parsing xls and xlsx files. It is still modest by modern standards :)
About MS Excel, it is NOT the only software that can create Excel files Star/Open/LibreOffice can edit them too. And being as simple as decision tables LTables requires, there shouldn't be any compatibility problem.
Also other well know tools use excel for decision tables (read it JBoss Drools)
精彩评论