Software Development - Table Driven Programming in Java - RoboProg's

RoboProg's / Software Development

Last Month


Jun 22, 2012

Specs in My Code?

I am of course talking about specifications, not spectacles. Meaning, in many cases there will be a small table that looks somewhat like a spreadsheet in your specification. One (or more) column(s) will have some condition or minimum / maximum quantity, and the rest of the row will be a rule describing the policy to be implemented in that case (perhaps a rate? perhaps a series of flags triggering or disabling some actions?) If you have requirements in such a tabular format, or can convert them into such a format, this is a golden opportunity to implement a solution in a "table driven" (or "data driven", if you prefer that term) fashion.

Consider the following pricing table:

Up to N widgets Price per widget
10 1.50
100 1.00
1000 0.95
2000 0.94
5000 0.93
10000 0.92
20000 0.91
(more) 0.90

A naive approach would be simply start coding as many else-ifs as needed, coding each calculation in the body:

Original, bad, code
See the getRate() function / method.

It's not pretty, but at least it works, as indicated by this test output:


rob@hyperion:~/proj/tbl_java>
$ $JAVA_HOME/bin/java BadDemo
Extended cost for 5 widgets: $7.50
Extended cost for 25 widgets: $25.00
Extended cost for 125 widgets: $118.75
Extended cost for 625 widgets: $593.75
Extended cost for 3125 widgets: $2906.25
Extended cost for 15625 widgets: $14218.75
Extended cost for 78125 widgets: $70312.50

rob@hyperion:~/proj/tbl_java>
$ 

A better approach would be to move the rate table policy (subject to change at the whims of The Management) into data, and to make a lookup which scans that data for the appropriate case.

Revised, good, code
See the getRate() function / method,
and the RATE_TBL array.

Once again, we run the test stub, and get the same (expected) output:


rob@hyperion:~/proj/tbl_java>
$ $JAVA_HOME/bin/java GoodDemo
Extended cost for 5 widgets: $7.50
Extended cost for 25 widgets: $25.00
Extended cost for 125 widgets: $118.75
Extended cost for 625 widgets: $593.75
Extended cost for 3125 widgets: $2906.25
Extended cost for 15625 widgets: $14218.75
Extended cost for 78125 widgets: $70312.50

rob@hyperion:~/proj/tbl_java>
$ 

Once we have the code at this point, it's not too hard to imagine removing this data from the code entirely, perhaps putting it in a database table, or in a property file -- maybe even reading the Excel spreadsheet or XHTML document given to you with the original specification! Of course, you could also figure that you will only change this data about once a year after initial development, and simply leave it at the top of the source code file, perhaps with a TODO comment to externalize it if you have to change it too often.

As food for thought for a more complicated case, perhaps your table looks more like string selectors, with a series of true/false values describing actions to take? Such a case could be encoded by using a Map with the selectors as keys, and instances of some class which takes the flags as arguments to its constructor as its values. Also consider the effect such an implementation might have on the memory footprint of your code: Only one copy of HashMap (or similar) class code need be kept in memory (it's probably already there, right?), and one copy of your flag value class need by kept. Otherwise, you have this sprawling method code full of one else-if after another, each having a body of steps of various permutations of the same actions.

Command Flag Action 1 Action 2 Action 3
ANNN
BNNY
CNYN
DNYY
EYNN
FYNY
GYYN
HYYY
PNYY
QNNY

Want to know more?

Steve McConnell has quite a bit to say about this topic in his book, "Code Complete" (yes, there's a 2nd edition that uses Java instead of Pascal for the examples).

Dave Thomas also has an essay on table driven programming online, for those of you not about to run out and buy a book because I suggested it. (Not that Dave Thomas, this Dave Thomas, whom I had the good fortune to hear a few weeks ago at the 2012 Atlassian conference)


("month"? Who am I kidding...)


Contact me:
r
o
b
o
p
r
o
g
@
yahoo.com

Copyright 2012, Robin R Anderson