Hacker News new | ask | show | jobs
by zeemonkee 5440 days ago
I think a lot of the Java hate is because of the architecture astronauts who hijacked the language in the last decade - J2EE/EJB, the GoF, FactoryFactoryFactory shit and so on. I remember seeing the earlier versions of the servlet API and it was very elegant and well designed; unfortunately once the astronauts were through with it writing Java web apps became such a form of mental torture (Struts, anyone?) that even PHP was a welcome relief, let alone Rails. My hate for it came from having to use some shitty app server like WebSphere because the coding-averse CTO considered it a "standard".

Looking at more recent work such as the lovely Play framework and the influence of new JVM languages such as Clojure and Scala, it looks like things are improving in Java-land. It's still a bit dated and clunky compared to Ruby and Python (let alone Clojure/Scala or even Groovy) but it's not as bad as people make out.

5 comments

As someone who was deeply involved with Java a decade ago, I feel your pain over the "hijacking." In truth, that crowd would have hijacked anything that came their way, it is a dynamic strongly influenced by the BigCo culture, it isn't really a tool thing.

The moment you set up "throw it over the wall" processes where architects are rewarded for architecture and implementors are blamed for bugs, you are going down the road to something that looks like J2EE no matter where you start.

That is precisely the root cause of it. Well spotted.
... architecture astronauts who hijacked the language in the last decade - J2EE/EJB, the GoF ...

Thank you for writing this. When I first read the GoF Design Pattern Book I thought "this is the reason, why the code in my project is bloated, unmaintainable and shitty".

You are right. The GoF only promoted bloated code. Who in their right mind would use patterns like the Observer, the Adapter, or the Visitor?</sarcasm>

Not sure if you know the history, but the authors of the book really only collected the patterns that they had seen around them in Smalltalk and C++ code. They wrote a catalog so we could all refer to the same name instead of using different names for the same concept. They identified the common problems that these patterns tried to solve and they also identified the trade-offs. Oh yes, they identified trade-offs!

Unfortunately, many developers thought that they had to put as many patterns as possible in their code, which was not the intent of the GoF. Ralph Johnson said that they received emails like "I have now used 15 patterns in my project, do you think we should use more?"

Andrzej mentions in his blog post that Java (and C++) lacks dynamic capabilities so this is why sometimes, you need these design patterns to make your code more easily extendable. Other patterns are good even with dynamic languages (observers...).

> Observer, the Adapter, or the Visitor

It depends on the programming language one uses, really. You won't find many references to these patterns on Python's mailing list (or at least I didn't when I was new to the language and used to spend a lot of time there, ~6-7 years ago). Also, when I've tried to learn Lisp or Erlang I didn't find any mentions to such particular patterns (or maybe only in passing), the focus was on something else. And I'm sure there are a lot of other languages outhere who don't bother with patterns.

You did not hear about observer, but you probably heard about publisher/subscriber (most gui frameworks use this, even wxPython with pubsub).

Adapter is a generic name. Compatibility modules that enable python code to run with python 2 and python 3 are adapters. For example: https://github.com/bartdag/py4j/blob/master/py4j-python/src/...

As for the visitor pattern: http://docs.python.org/library/compiler.html#module-compiler...

All languages have patterns. Case analysis is a common pattern in Lisp code I've seen. Another one is map-reduce. Tags are another one.

They're just not called design patterns. But note that the things in GOF weren't called design patterns in C++ until 1995 either (the GOF book largely predates real use of Java). They were called techniques, or just things you might see in multiple projects.

Every language has design patterns. The patterns are different depending on the language, though. You don't use the observer pattern much when you've got proper delegates (or closures), for example. Design patterns are just the things you end up doing over and over in a language. MVC is a design pattern. Even something like Rails itself could be said to be a codifying and standardization of a set of design patterns.
Exactly. What many GoF critics seem not to understand is that Design Patterns is descriptive, not prescriptive. It's "what we've seen," not "what you should use."
I've heard people say that, but if that's true, why didn't they include many of the (much more commonly used, IME) patterns like Big Ball of Mud, Stovepipe System, Spaghetti Code, etc...? There's lots of nightmarish patterns/techniques that were omitted. I find no plausible way to account for that other than that the patterns are (perhaps implicitly) prescriptive.
Those are covered in the anti-pattern book.
Reinforcing my point. If those are "anti" patterns, they must be bad, right? Hence, patterns as described in GoF are good.
No sarcasm necessary.

I am pretty convinced that GoF did not expect how popular their book may become. Looking back, it is always easier to judge.

Looking back, with no offense to GoF, what happened can be understood. GoF did a great work for all these "I badly need to sell something new and hot to all these saturated development shops" guys. Read the pattern book once, teach it a hundred times for 2000$ a person. Great stuff.

Now, of course it is due to the single developer to use patterns or not. But the average developer is - well average. Using a pattern is much easier than to understand, when to use and when not to use.

I indeed should have been more precise in my statement: our code got bloated and unmaintainable because there are pattern all over. This is not GoFs fault, it is the fault of all the developers who just read the book and want to apply everything instantly, everywhere. It is also the fault of the community, who did not recognize at once, that pattern should be used only, if they solve a problem that is hard to solve without patterns.

I've worked in shops where GoF ruled. Everything was a factory, even the things that /weren't/ factories were being /called/ factories, and there were zillions of singletons peppering the landscape.

"You've got a singleton class with a single method and no members . . . why don't you make this thing a function?"

"Uh, it wouldn't be a pattern then, would it. Um, would it?"

And the XML. Oh, dear Lord. I have a doctor's slip now stating that I am allergic to XML and that's the reason I'm breaking out in hives, whooping for air and leaving the room.

I sometimes wonder what would have happened to the software industry if the entries in GoF had been written in a different order. Would we see a plague of Visitors and Observers?

I do think GoF has it's place, and every serious programmer should be familiar with it; if only to know what to avoid.

[edit] I didn't mean to sound so negative about GoF. Know the patterns so you know when to use them, and when to avoid them. You can't debate these decisions when you're ignorant of design principals and history.

Jive turkeys who apply patterns for the sake of applying patterns are the reason the code was bad. But don't blame the GoF.
I love the term "architecture astronauts", and you get them everywhere in this field, not just programmers.

I agree that it's not java the language (java's boring, but not unusable), it's the java culture from the last decade that drives people away.

No, there's a direct relationship between the architecture astronauts and Java-the-languages. Since Java is so simple and so lacking in abstraction mechanisms compared to almost anything else, you end up writing FactoryFactories and all the facades and all that code goop just to get any sort of halfway decent abstraction out of the language. Even things like the AOP libraries that directly muck with JVM bytecode are a direct consequence of the fact that Java-the-language is so brain-dead that it's actually easier for them to directly fiddle with bytecode than work at the Java-language level.

This lack of abstraction mechanisms was by design; it was supposed to be simpler than C++, and it is. Unfortunately, it came from an era where people still thought OO was the uberparadigm and it met every need in it simplest form. I think I can safely close the book on that as being false; at the very least you need OO with borrowed features from older-generation functional languages like closures and first-class functions, like Python or Ruby.

I do understand why there was a need for all these abstractions, but I just think it got way out of hand. "Programming" java became more about gluing frameworks together using XML than about writing code. The culture of enterprise java programmers directed people to bring in all these abstractions, "just in case" they might need them in the future. The language may be neutered, but the over-architects took the last bit of fun out of it.

I've really only been viewing this from the deployment side for quite a while, but when I'm trying to help you troubleshoot your relatively simple webapp, and I have thousands of lines of stacktraces that bubbled up through a half dozen frameworks, it's hard to blame just the language.

On the other hand, the last half decade shows a major improvement in the Java community.

Have you tried Java EE6 (the app-servers that support Java EE6 or just the subset of Java EE6 have improved significantly as well via OSGi).

I agree with you about Play, it seems encouraging though I haven't used it for anything other than the tutorials on the site. Still not sure I'd want to use it over Rails or Python.

I'm worried that people will think I'm a broken record on the topic of java, but this discussion is coming up a lot these days, and I think a lot of people are doing a mental re-evaluation of Java. One thing that comes up a lot is that Java itself isn't terrible, but J2EE (as well as Spring and other frameworks many developers consider over-complicated) has made the experience of being a java developer (especially someone new to the environment) unpleasant.

While some people mention frameworks like Play, I'm interested in what people think of going back to the Servlet + Libraries approach that was common in 2004, just before Struts/Spring hit the scene. It's verbose, and I'm not saying we should just go back to the way things were, but I think developers might want to embrace the low levelness and verboseness of Java.

My take on it is - if I'm happy to work within the conventions of a framework, then I'd probably be happy with Rails or Django. If I want to write Java, then I probably want a very detailed level of control over my code base. In this case, it might make sense to start with the bare-bones (servlets and jdbc), and grow into what I think I need through libraries rather than an over-arching framework like Spring.

In general, I think I would want to use MVC and DI, but I'd like these things to be as unobtrusive as possible, and easy to add or remove, like libraries rather than something that dominates my code from the very beginning...

Honestly, my thoughts aren't completely formed on this yet... I just find it interesting how so many people on HN are starting to discuss this now. Often, there's a reason that developers start to focus on a particular issue at the same time.

>> a form of mental torture (Struts, anyone?)

If I had to name the single biggest class of make-work in my life in the last 10 years, that would be it: maintaining legacy Struts crap.

The creator of struts should be in Gitmo for a year or two, perhaps with access to a functional programming environment a few hours a week if he behaves himself :-)

Java: providing a job with benefits. Like the episode of "The Simpsons" where Homer has to go back to the nuclear power plant to work, to pay for his daughter -- "Do it for her."