Hacker News new | ask | show | jobs
by nervechannel 5624 days ago
As a counterpoint, I like this quote from Twitter's Nick Kallen:

This smacks of the oft-ridiculed Java AbstractFactoryFactoryInterface. But let me put it bluntly: AbstractFactoryFactoryInterface's are how you write real, modular software–not little fart applications.

http://magicscalingsprinkles.wordpress.com/2010/02/08/why-i-...

[N.B. I'm not saying there isn't a lot of truth in the factorial article, it's just you have to know which challenges just need a one-liner function and which require an AbstractFactoryFactoryInterface]

3 comments

I've read that article twice in the last few months. When I was writing a lot of Java I thought "Oh, you know, that actually makes some sense." Now that I've returned to writing Ruby full time, I look at it and think: "Hey, wait a minute..."

All we've done here is forced the programmer to adhere to some ridiculous interface which requires just as much understanding of the internals of the code as overriding the method in the first place. You also end up with hard-to-understand naming schemes, which leads to two points of confusion:

1. Which one of the provided query factories does what I actually want? 2. If I need to write one myself, what would I call it?

PerQueryTimingOutQueryFactory? You've added more parts to that name than would have been included in an option to the query function! Oh, and it still doesn't include the information necessary to run, because it folded the timeout specification down into a HashMap. One more thing for the end-programmer to understand.

There are good places to use dependency injection. There are also places where Factories are exactly the pattern you need. But in most dynamic languages, you can achieve these effects implicitly through inheritance and closures, and it cuts down the complexity of the code immensely with only a minor cost to reusability.

This guy works for Twitter. They control Querulous. He could have just added a :timeout argument which takes an number or a function returning a number to the query method, but now you have to understand all this additional architecture to get anything done.

> When I was writing a lot of Java I thought "Oh, you know, that actually makes some sense." Now that I've returned to writing Ruby full time, I look at it and think: "Hey, wait a minute..."

And thus you demonstrate using Java for prolonged periods may cause brain damage.

Sometimes I wonder if Java's "classplosion" is actually a subconscious backlash against the type system. In order to get anything done within the narrow box of its static type checking, you're forced to apply insanely convoluted indirection, pushing the code you want to be polymorphic up into factories and ByzantinelyComposedClassTaxonomiesWithIncreasinglyUnreadableNames.

I'm not sure how to actually prove that, though.

If it's a subconscious reaction to static typing, we would see it only in subjects who already had contact with dynamically typed languages who are forced to use Java and its straitjacket.

After being exposed to Java for prolonged periods of time, my Python programs became classes with a main method that was called in an ifmain condition...

It doesn't even take prolonged periods (for me at least).

I was participating in an obfuscated code contest a while back (making a simple command line multi-function calculator), and since I knew I couldn't compete on line noise I decided to try obfuscation through architecture. Somewhere around writing a RightSideOperandInterface (so I could catch division by 0), it managed to get into my head that it was actually more robust and extensible than doing it any other way. I came to my senses slightly after submitting it.

I think your second paragraph hits the nail on the head. What's the point of writing an architecture that's extensible if it requires the user to know all of your code in-depth to use it?

Now, if the code was packaged as an API with very good documentation, then this might be a moot point. In my personal experience, this has rarely been the case.

There's nothing wrong with AbstractFactoryFactoryInterface if that's what you end up with after carefully evolving a design, driven by actual requirements.

The problem is that the people who come up with these designs are the ones that consider refactoring bad/hard/risky. They know very well that they need a hammer, but 200 what ifs later, they have this monster-factory, instead of just getting a bloody hammer, then, when they also happen to have a screwdriver and a saw, they build a toolshed, and refactor.

Agree, in my experience it's people who write-only code that tend to over engineer things. If you can't read or maintain code it better be pretty flexible when you write it!
There's configurability by configuration, and configurability by composition.

You can have a LoggingQuery(TimeoutQuery(Query())) or a EverythingQuery(timeout = true, logging = true).

From what I've seen, @nk loves composition.