Worse-Is-Better Design or Sloppy Code?

Although most of you probably heard of this before, today Worse-Is-Better triggered a chain of thoughts in my head that goes way back.

When I entered the Java development community the hot stuff in my side of the aquarium were RUP, UML and Design Patterns. The approach to software engineering that I learned was to foresee as much as I can and put those ideas in the design. As many others I would often use a design pattern where it fitted, without giving thought if it was really necessary there.

As a result of that Aranea was born. From the point of view of software design Aranea was almost perfect. It was based on independent components with few interdependencies, it foresaw situations like AJAX and desktop deployment long before they were implemented.

By the time we started working on JavaRebel I got somewhat disillusioned in those practices. Therefore, although I originally wrote a throwaway prototype, we ended up evolving it without ever rewriting entirely. Although the code was not directly a mess, it definitely preferred simplicity over unnecessary abstraction and not a single design pattern was hurt while hacking at it.

Both projects were large and complex enough to serve as a case study. But like the original author of the “Worse-Is-Better” essay, I still can’t choose between the two. In fact, I’m not even sure that these are separate approaches, it may very well be just the amount of sloppiness the project can take before it collapses.

Now, sloppiness is a good negative word. It is also fitting, since it refers to the character of the development process, rather than its success.

A very good example of sloppiness in today’s Java ecosystem is Hibernate. It is designed with simplicity in mind and it’s code is a tangled mess of just enough design. Nevertheless it’s a hugely successful project which provides a clean enough API to make developers happy. It is designed evolutionary and at some point developers had to give up full backward compatibility for new features.

On the other side of the scale is Spring. It’s code is precise, well organized and object oriented to the point of nausea. It has a layered design with the simple abstract core and never had to sacrifice backwards-compatibility.

In their own way both these projects are about equally complex. And I don’t mean lines of code, but rather how hard is it for a newcomer to start hacking at their code. In the end it’s almost as hard to unravel the layers of abstraction as to jump through the sloppy code. The main difference is perhaps that Spring offers more extension points whereas Hibernate is somewhat harder to debug.

“Wait”, you say, “Does he really suggest that sloppy code can be good? Why just yesterday I had half a heart attack looking at it!”. The trick is that I’m comparing two highly successful open source projects made by some of the best people in the Java community. This makes a whole lot of difference.

In the end it’s unsurprising to come to the thesis propagated by the agile community: in the hands of the right person any approach will work. A talented leader will trade the right things for sloppiness and a clueless newbie will create an overcomplicated abstract mess. My experience tells me that in my next project I will use just as much sloppiness as the project will take without collapsing and make sure the people around me can handle it as well.

What do you think? Can discipline protect a project or will it create even more complications? And what should be the guiding star when designing it?

Tags:

  • http://devsmt.blogspot.com smt

    that’s an amazing question! try with me this answere:
    love is the guiding star.
    love your business logic, love your tools(language, platform, standard…), love your users and peers.
    when you want to take control aver people with discipline or escape from responsibility with laziness, or force your tools to be what they are not, love is not driving you, and your code will be the mess your brain/life is.

  • Simon

    smt: Very well said. :)

    Another good example of sloppy but good code is Ruby on Rails.
    It is only over-engineered in a few places, and the code feels organic. Can’t be fun to maintain, but sure is a joy to use.

    - Simon

  • jelmer

    Hibernate and spring equally complex. My goodness.. surely you jest.

    I’ve run into so many hibernate bugs i’ve lost count and not once have i been able to solve the issue myself.

    In Spring on the other hand i’ve rarely found a bug and when i did the problem was most always easy to debug and solve.

    Springs abstractions make for really clean and concise code while hibernate’s “sloppy code” is constantly causing bugs that are impossible to solve for the uninitiated

  • Jevgeni Kabanov

    jelmer: I might have cheated here a little. Perhaps Hibernate is not the *best* example of sloppy, but good code. But I wanted to choose equally successful and well-know projects for an example.

  • Tero

    Good design is not an excuse for sloppy code but it certainly makes sloppy code acceptable in some less critical parts of your system.

  • Nikem

    I am totally agreed with jelmer. Hibernate’s mess is just that: mess. And I will not ever give my vote to Gavin King as “one of the best people in the Java community”, sorry pal.