It is Java's particular set of features and lack of features that give programs written in it a tendency towards design patterns like the one described.
- Everything's an object -> Let's define lots of nouns!
- Classes cannot be declared to implement interfaces after the fact -> Let's write some adapter classes!
- People get tired of writing adapter classes and notice that JVM has reflection capabilities -> Let's make a framework that generates adapter classes as needed!
- Everything's heap-allocated -> Let's avoid excess allocations by re-using objects! Which means you've got a big web of interlinked mutable thingamabobs floating around, made possible by Java's pretty-good GC.
- 'const'ness ('final'ness in Java-ese) is defined on the type, not on where it's used -> Most classes are written assuming mutability, and if you want immutability, you need to create an entirely separate type hierarchy.
I could go on.
When I want to write a Java program but keep it simple, I usually end up writing something that looks more like a C++ program. Minimal, domain-specific classes with as much setup in the constructor and as much `final` as I can get away with. But it's not as ergonomic a language for writing programs in that style as C++ is. And once a coworker brings in some library written in the conventional combinatoric-explosion-of-classes-and-pointers-to-mutable-objects-everywhere style, you're pretty much stuck with it.
- Everything's an object -> Let's define lots of nouns!
- Classes cannot be declared to implement interfaces after the fact -> Let's write some adapter classes!
- People get tired of writing adapter classes and notice that JVM has reflection capabilities -> Let's make a framework that generates adapter classes as needed!
- Everything's heap-allocated -> Let's avoid excess allocations by re-using objects! Which means you've got a big web of interlinked mutable thingamabobs floating around, made possible by Java's pretty-good GC.
- 'const'ness ('final'ness in Java-ese) is defined on the type, not on where it's used -> Most classes are written assuming mutability, and if you want immutability, you need to create an entirely separate type hierarchy.
I could go on.
When I want to write a Java program but keep it simple, I usually end up writing something that looks more like a C++ program. Minimal, domain-specific classes with as much setup in the constructor and as much `final` as I can get away with. But it's not as ergonomic a language for writing programs in that style as C++ is. And once a coworker brings in some library written in the conventional combinatoric-explosion-of-classes-and-pointers-to-mutable-objects-everywhere style, you're pretty much stuck with it.