
A FactoryFactoryFactory in Production - hliyan
https://hackernoon.com/a-factoryfactoryfactory-in-production-822478b5afbd
======
ganonm
What is up with the seemingly popular knee-jerk reactions towards OO design
patterns? It genuinely feels like some sort of mass hysteria... Yes,
strategies like dependency injection might seem like pointless complexity if
you don't examine why they exist in the first place, but they do solve genuine
problems. And no, these aren't just problems that wouldn't exist if you used a
functional language... (no silver bullets or else we'd all be writing Scala or
Haskell)

Yes Java has a lot of problems but they are mostly ones that have workarounds
and aren't fundamentally dealbreakers. A few example issues are assignment
isn't final by default, @Override isn't required to override methods, you
can't have abstract static methods (sort of can workaround this now get this
now with default interface methods). Java is basically just a really un-
opinionated language that requires careful practices to wield it properly (see
Effective Java by Joshua Bloch) but other than that it isn't a completely
terrible language and you can write some really robust, easy to read code with
it.

I would also have a lot more time for this article if the author actually took
the time to explain the motivation behind the *FactoryFactoryFactory class
instead of just discounting it without explanation and using it as the
proverbial Straw Man for his article. I'm sure something this unusual must
have a very interesting reason as to why it exists (I'm taking him literally
here and assuming he isn't just exaggerating for comic purposes).

~~~
monocasa
I've personally seen the kind of engineers who simply pattern match rather
than thinking things through go into nesting as many GoF chapters as they can
into a commit. I was literally told during a code review when questioning what
these layers were achieving for the product that 'all abstraction is a benefit
since you can then always work at an even higher level'.

Java for whatever reason seems to attract these ideas.

~~~
api
My pet speculation on why Java attracts this stuff is that it's actually a
very robust and strongly backward compatible (and forward compatible) language
that runs on a very robust VM.

I can take a compiled .jar file from the late 90s and in quite a few cases I
can run it right now unmodified. I can also link against it and use it in Java
code pretty trivially. I can do this with modern tools and modern VMs. Then I
can copy the result from an x64 box to and aarch64 box and most of the time it
will run the same way. That is just amazing.

Java's strength in the areas of robustness and compatibility means it can
sustain a lot of complexity. You can build really insanely complicated towers
of Babel in Java and they won't topple over. Java's excellent tooling means
they'll even be somewhat _maintainable_.

This transforms Java's great strengths into its great weakness. Its capability
to sustain complexity means that nothing checks the tendency of sophomore
programmers to over-engineer everything. In other languages over-engineered
rococo monstrosities just fall over, but in Java you can actually _get away
with it_ to a shocking degree and still ship working robust code.

Try that kind of over-engineering in C++ and you'll have 20 minute compile
times for small projects. (I've seen this, so people still try!) Try it in a
dynamic language like JavaScript or Ruby and your complex design pattern
monstrosity will become a non-deterministic generator of random runtime bugs.
These languages can't sustain code that is riddled with
FactoryFactoryFactorySingletonFactoryObserverFactory type stuff. Java can, so
the Java ecosystem is where the people who love to over-engineer go.

~~~
crdoconnor
My pet speculation is that Java programmers are culturally predisposed to, and
are typically _proud_ of creating towering architectural ziggurats with at
least 3 layers of unnecessary abstraction.

It's the only language for which I've ever met "architects who didn't code".
It wasn't backwards compatibility that made that happen.

~~~
seanmcdirmid
Java today is used heavily in the enterprise, which thrives on utilizing
marginal talent. Java didn’t look that way in the 90s, and anyways, I bet
you’d see drastically different kinds of code comparing enterprise and
Android.

------
fragsworth
I've worked with a lot of different languages, developing games and server
software, for 15 years. I and everyone I've worked with always tries our best
to give reasonable, readable names to things. I've never needed to call
something a "Factory". Let alone a "FactoryFactory" or
"FactoryFactoryFactory".

I don't know what it is about Java that makes people write code and name
things like this.

This kind of stuff is just foreign to me, and I just don't understand any of
the rationale behind it. I hear about it all the time, but can't fathom how
code ends up like this.

~~~
beager
Well, a factory pattern is a well-defined pattern in OO software design, and
one that a developer of any experience level can look up and understand. Your
particular implementation may give rise to a more plain and contextually-
accurate name, but if you call it something other than a Factory, posterity
may need more time and context to discern what your code does.

If I'm a new developer on a project, I know what a SprocketFactory does, and I
know that I'm going to get SprocketFactorys from a SprocketFactoryFactory, and
I know that if I call the SprocketFactoryFactoryFactory, I'm sure as hell
gonna get back a SprocketFactoryFactory, which will then give me a
SprocketFactory, which will then produce Sprockets.

~~~
chimprich
If I'm a new developer on a project and see a class called
"SprocketFactoryFactoryFactory" I'm probably going to cry for a bit and wonder
whether I couldn't have got a better gig, and then try to figure out a better
way of producing sprockets.

Human short-term memory only has a size limit of about 4 simultaneous chunks
so once you're juggling those levels of indirection any development is going
to be glacially slow until you've acquired a great deal of experience with the
codebase.

Out of interest, can you describe a concrete case where multiple levels of
factory patterns have actually been justified and resulted in simpler code
than an alternative?

~~~
nitrogen
If Java had default parameters and named parameters I think a ton of the need
for Builders and Factories would go away.

------
Pharylon
I've never done heavy development in Java, but my day-to-day has been C# for
years. I've never seen a FactoryFactoryFactory, or even a FactoryFactory.
Since the two languages are so similar, I would think C# would have the same
issues as Java in this regard, but in my experience it doesn't. Is there
something about C# that has let it avoid this? Or have I just happened to work
at places that don't like the Factory pattern as much as everyone else seems
to? :D

~~~
WorldMaker
C# often has "release valves" that allow you to divert from some of the mess
that Java tends to exhibit. `events` and `delegates` from C# 1/.NET 1, flawed
as they may be in retrospect, alone simplify several major patterns that Java
falls into.

I also think on the paradigm issue here is Java architects seem more inclined
to have a "ravioli code" problem. There's an ancient Java ideal of
componentization [1] that a lot of Java code tries to live up to. Lots of
little components boxed into tight containers that only ever interact through
often "reconfigurable" sauce: ravioli.

There are some benefits to that ideal, it exists because it has some merits in
terms of component testing, in particular. It's just that as with spaghetti
code and copypasta code, ravioli code also sometimes winds up in a mess where
the ideal meets the real world, and somehow a toddler (or junior developer in
this analogy?) has thrown it all over the kitchen and you have no idea how to
clean it up without destroying the entire kitchen and starting over... May not
be a great analogy. ;)

I'd argue that you are more likely to see Java-style ravioli code in C#
projects that use IoC containers of one sort or another. Again, there's
nothing particularly wrong with IoC containers [2] as an idea connected to
some ideals of component testing, it's just that it's an ideal that often
falls down and fails to deliver its advantages in the real world.

[1] That somewhat resembles the Smalltalk ideal of object message passing
while the language itself lacks much of the architecture for that. Arguably, a
lot of Java's worst problems come from trying to replicate a lot of Smalltalk
ideas and design patterns in a language that is nothing at all like Smalltalk
and misses some important characteristics of Smalltalk.

[2] IoC Containers are a ravioli concept directly imported to C# from the Java
world, with the earliest IoC containers such as Spring.NET being Java ports.

------
jmull
That's pretty funny, but EventFactoryFactoryFactory isn't exactly Java's
fault.

There's a software development culture that believes adding a layer of
abstraction is the answer (doesn't matter what the problem is) as long as it
has a GoF pattern name (doesn't even need the implement the pattern its named
for).

For whatever reason they've adopted Java, but if you're going to throw
abstractions on top of abstractions carelessly you're going to create a mess
of spaghetti no matter the language or environment.

(I think the preference for Java is just an accident of timing of when the
culture arose. The responsibilities of corporate IT groups were exploding and
they needed a language for all the software they had to create. Java was there
and it was a good choice.)

I'm feeling bad about my laughing and complaining, which is useless, so here's
some practical advice on restraint when it comes to using abstractions and
patterns:

* Don't use an abstraction to wrap something you don't understand well. You may feel like you've tamed a confusing, complicated API and turned it into something you do understand and can use effectively. But you've actually just rolled up all the things to didn't account for and don't understand and hidden them away from view where they will explode if your software actually sees much use. I realize this isn't always easy to avoid doing, but at least never wrap something in an abstraction _because_ you don't understand it that well. And when you're forced to implement an abstraction on top of an API you don't understand well, go through the API, method (or function or endpoint or whatever) by method, and look at all the options and ask yourself what each of those options and methods are there for.

* When considering using a pattern, make sure to check the section titled something like "When Does This Pattern Apply?" and make sure the abstraction you're considering actually solves the problem.

~~~
geodel
I look at JDK codebase it has about 360 factory classes. I look at popular
Java project: Gradle, it has about 350 factories. My project at work has about
50 factories.

I agree that Factory* is not Java's fault. However I think Factory phenomenon
did not start with corporate IT but by people working on core JDK or big open
source projects.

~~~
jmull
I should clarify:

I don't have a problem with the factory pattern. I have a problem with piling
abstractions and indirection on top of abstractions and indirection to create
spaghetti systems.

I don't know how EventFactoryFactoryFactory is being used but it looks like
we're dealing with four levels of abstraction simultaneously, which seem
likely to me to be a horrible failure of design. (I'm kind of assuming this
isn't an event planning system, or something, and that "event" is an
abstraction for something happening.)

------
georgeecollins
This is a great critique of a coding style, but not really a language. Being
an older person, I can appreciate how much object oriented languages helped
organize complex code. But then it became a religion and we got the silliness
the author describe. Keep in mind, no matter how smart you are, something you
are doing today is going to seem really dumb twenty years from now.

------
lostmsu
This article has no insights whatsoever.

------
stevenheidel
Author here, I also wrote a more in-depth article on how to apply concepts
from functional programming to languages like Java 8:
[https://hackernoon.com/practical-functional-
programming-6d79...](https://hackernoon.com/practical-functional-
programming-6d7932abc58b)

~~~
haltingthoughts
I think most would agree FactoryFactoryFactorys are bad. But how does one fix
this? What's the alternative? Maybe a post on how to disentangle one of these?

------
vilhelm_s
Eh, are Haskell programmers really in a position to throw stones here? I mean,
in Haskell terms, a FactoryFactory corresponds to something like

    
    
      type EventFactory = () -> Event
      type EventFactoryFactory = () -> () -> Event
    

which seems fairly innocuous. Meanwhile, Haskell programs have gems like

    
    
      type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)

------
vorotato
Is there anything a factory does that currying wouldn't solve?

------
jlebrech
"are you sure you want to delete this repo?"

~~~
bitwize
Let the past die. Kill it, if you have to.

