Java anti-featured as a Pattern Language
Java the language is a great algebraic assembler for the Java virtual machine, but it's not much of a pattern language. It's even anti-featured. Here's an example.
The overarching development model I'm using on PigIron is that the inner stuff knows little about the outer stuff. PigIron is a 1.5-developer open source project. It's not quite massive, but it's large, layered and complex.
This TISKLATOS pattern :) makes it easier to develop in spurts as time permits. It also enhances reliability in that making changes at midnight is safer than it might be otherwise: keep your sleepy fingers out of the inner stuff while working on the outer stuff.
It's a very reasonable sort of design pattern to follow ... I certainly didn't invent it personally.
At the outer fringe of PigIron is the translation of PigIron VSMAPI transactions to-and-from JSON so that they can be used in web applications. Each type of VSMAPI basic parameter extending VSMParm has its own method for translation into JSON. These translation methods are public static in the Argument class which is distantly external to VSMParm.
{geshibot}
/**
* Assimilate a VSMParm as an Argument
*
* @param vsmParm A VSMParm instance to be used as an Argument
* @return An Argument created from the type
* @throws JSONException on JSON err
*/
public static Argument from(VSMParm vsmParm) throws JSONException {
Argument result = null;
if (vsmParm instanceof VSMInt) {
result = from(VSMInt.class.cast(vsmParm));
} else if (vsmParm instanceof VSMString) {
result = from(VSMString.class.cast(vsmParm));
} else if (vsmParm instanceof VSMAsciiZ) {
result = from(VSMAsciiZ.class.cast(vsmParm));
} else if (vsmParm instanceof VSMStruct) {
result = from(VSMStruct.class.cast(vsmParm));
} else if (vsmParm instanceof VSMArray) {
result = from(VSMArray.class.cast(vsmParm));
} else if (vsmParm instanceof VSMAsciiZArray) {
result = from(VSMAsciiZArray.class.cast(vsmParm));
}
return result;
} {/geshibot}
Now, in a single-inheritance language (which has cost me many keyboard hours in making up for that lack of dual inheritance since I adopted it as my main development language in 1997), why do I have to downcast? Why can't I just pluck from a Vector and toss to Argument.from() with an implicit downcast automatically selecting the approrpriate overload of Argument.from()?
My friend Nathan Lipke, a Sr. Member at Oracle, says my design is wrong "and looks foreign to a Java developer" (making me a Stranger in a Strange Land). He points out correctly that abstract methods in VSMParm would work as well.
That's the very point: that Java the language erodes the chosen design pattern and development model. I don't want tutti-frutti JSON-oriented abstract methods cluttering the very simple core of PigIron's mainframe communication API. It doesn't make good development methodological sense.
But it's either that, or rote downcasting (rote jobs are automation candidates, yes?) in service of the overloads in the outer layers. For that matter, plugging in abstracts in base classes is pretty rote itself!
For these and other reasons, one might conclude that Java the language is a great algebraic assembler for the Java virtual machine, but it's not much of a pattern language.

