"Jadoth" is a kind-of-acronym for "Java dot h". It is a (somewhat funny) allusion to header files in C/C++ (dot h) and hints to the programming paradigm to define everything that is used as a type as an interface instead of a concrete class at first and include the actual class as a nested class called "Implementation" inside the the interface.
Here's the motivation for it:
If you think about it, is it really the best thing to do to define a type (an interface), say named "MyMessageProcessor", and then define an implementation (a class) named "DefaultMyMessageProcessor", and that for EVERY type in your project? If you have once seen a project with dozends of "Default~" classes next (or even in an abused neighboring package exclusively created for grouping all the "Default~" stuff) to the actual types you (at least me) can't help rolling eyes; then if you even want to quickly find a certain implementation in the IDE's intellisense but all you see is a large list of "DefaultThis", "DefaultThat", "DefaultSomethingElse", you can't help but think "come on, this can't be real!".
To get some relief, what most developers do is simply define their (actually architectural abstract) types as concrete classes right away and name the implementation itself "MyMessageProcessor". I did that too, in the past, blithely thinking "a class is sufficient here, I just only need one implementation at the moment anyway, and for the future... well that will surely be alright somehow". But of course at some point in the future, you pay big time for that little sin that grew with your program, either by having to expensively refactoring a concrete-class type to be an interface in the whole project (and all projects depending on it) or by being forced to say "it must stay a class because too much structurally depends on it already, damn...". Both things are nothing that anyone can desire.
The actual problem was the short-sighted decision in the first place to implement a type in the project as a class instead of as an interface.
But then there's still the ugly default implementation naming, what to do about it?
There's a better solution for that.
Recap what you actually want to achieve: You have a type ("MyMessageProcessor" in the example) and need a convenient default implementation of that type.
Wouldn't it be good to simply being able to write something like:
MyMessageProcessor.Default
or
MyMessageProcessor.Implementation
?
Well, that is possible. Right away.
Consider the following construct:
public interface MyMessageProcessor { // methods, etc. public class Implementation implements MyMessageProcessor { // implementation, etc. } }
That way, you can easily and perfectly clean object-oriented write things like:
MyMessageProcessor p = new MyMessageProcessor.Implementation();Or maybe
MyMessageProcessor p = MyMessageProcessor.Factory.newInstance();And even
MyMessageProcessor.Util.doStaticStuffWith(p);(btw.: that is, at least syntactically, although not truely bytecode-wise, the often-wished possibility to include static methods in the interfaces they belong to. I really wonder why hardly anyone mentions that possibility. At a closer look, it's not even a workaround but object-oriented-wise the clearer and thus superior way to the alternative of softening up interfaces to allow them contain method bodies on their own. And it even improves structure by visually grouping all static util methods in a properly named interface-inner-class)
This programming paradigm of including the default implementation of a interface in itself reminded me a little of old C's header files. Hence, the (a little humorous) expression "Java.h" or "Java dot h" was quickly found. And from there, to make a unique name of it, Jadoth.
Fancy naming or not, the important conclusion is:
NEVER name your default interface implementation classes "Default~" or interface util classes "~Utils", it will just ruin readability and seduce to drop clean interface architecture. Instead, embed those classes where they name-scopingly belong to, inside the interface they refer to. Instead, consider defining EVERY class, that is architectural meant to be a type (i.e. neither a static util method class nor a trivial helper class) as an interface instead. You can still include your desired implementation in it, for the small price of one sole intendation level btu with the gain of a much better program structure.
Keine Kommentare:
Kommentar veröffentlichen