June 28, 2005
Worst user interface ever
When you hack programs for a living, you naturally develop a resistance against badly designed applications, household appliances and the like. Some people like to call this resistance "user karma", but I think it's just the effect of having seen so much shit that you can see behind the stench.
Therefore it came as quite a surprise when today I was defeated by the user interface of a bag of cheese. This bag features a most miraculous opening mechanism, and in fact I have yet to figure out how to open it using the method envisioned by its creators.
I present Exhibit A:

An innocent bag of cheese, right? But wait until you try to open it!
There is a noticeable bar of thicker plastic covering the width of the top part of the bag, so it looks like it could be one of those resealable clips. Closer inspection however reveals that the clip is only attached to one side of the bag's interior. Clearly, the mechanism must be more sophisticated than your average resealable clip!
Surely having foreseen my bafflement, the bag's designers provided additional help. Here is a close-up of the priceless opening instructions in the top-right corner:

Ignoring for a second the messages written in a language I don't speak, it strikes that no part of the bag looks even remotely like that picture. Neither does any object on this planet I have ever seen. What is the bag trying to tell me? Press a clothes hanger against the cheese and wiggle?
Searching the bag for additional clues on how to open it I found a flap that looked like it wanted to be torn off very badly:

Feeling confident that I was doing the exact right thing for the first time, I tore off the flap and found... nothing! Behind the flap there is just more colorless plastic! What the fuck!
Of course I ended up opening the bag with a pair of scissors, but let me tell you that getting owned by a bag of cheese is in no way beneficial to your self-esteem.
Update: I figured it out!! After you remove the flap you must drill your finger between the two outer layers of plastic. After two centimeters of drilling you can reach the plastic clip, which you can open by pushing the upper part of the front side into the cheese and pulling out the bottom part. You now have a perfectly resealable hole in the middle of your cheese bag! Man wins over machine!!
June 26, 2005
How I learned to love static typing
Do you know what bugs me about dynamic languages? There's so much to type! I'm most serious. Having spent the better part of my programming life tinkering with Perl, I found that Java and Eclipse often lets me get away with a lot less typing.
Recently Philippe Ombredanne pointed me to the wonders of Hippie Completion (now "Word Completion" in Eclipse 3.1 lingo). Hippie completion can summoned from any point in your code and rather than making suggestions it just completes whatever you're typing - complete ownage. Once you get the hang of it, coding without Hippie Completion feels a lot like running uphill, in deep snow and your feet tied together.
The ease and speed with which modern IDEs allow you to generate constructors, extract interfaces, delegate behaviour, organize your dependencies and imports, split up spaghetti code into multiple methods and whatnot makes life so much easier. I also like how you can simply use a new class, field or method that does not yet exist and Eclipse will automatically create something suitable.
Don't even get me started about refactoring. When Perl requires to rename a class, variable or method using search and replace I feel like soldering circuit boards with a welding torch. Also when I have to change major parts of my API it's just nice to instantly know what I'm breaking, being able to jump to the problem with a single click and maybe even have Eclipse repair it automatically. For this purpose tests are about the lamest substitute ever.
Should we all be doing Java then? Hell no. The thing with Java et. al. is that it only rewards a single style of coding. Anything other than textbook OOP and the pain just keeps getting worse. My point is that if you find that static typing is slowing you down, take a better look at your tools. When you find yourself typing out pages of code, you're clearly doing something wrong.
June 18, 2005
Oxygen
Do you sometimes get sidetracked by architectural trips to the moon? I certainly do a lot so lately, and reattaching your feet to the ground in such a situation can easily grow into a project of its own.
My most recent trip to the moon started Friday afternoon. Twenty-four hours later I found myself staring at a method signature like the one below and knew something had gone horribly wrong:
container.set(Node n, Entity e)
First law of software design: Whenever you have a class called Entity it's time for atmospheric reentry. I closed the project, restored a version from Friday morning and, while I was at it, removed another dozen other bullshit abstractions indirections no one would ever need. My code might now be a little less versatile and generalized but that has so been worth the trade. You don't really appreciate oxygen until you stop breathing for a while.
June 09, 2005
More on software evolution
At the same time I wrote last night's entry on the misery of evolving interfaces, Cédric Beust published "Extensibility the interface way". While I do not particularly like Cédric's proposed pattern for dealing with versioned interfaces, I am always glad to read about people's ideas for reuse and software evolution.
One thing that keeps being mentioned in this context is Eclipse and, more recently, the Eclipse Rich Client Platform. From what I pick up from interviews and working with Eclipse, the impression grows that IBM is dead serious about reuse and being around for the long run.
No matter which side of the moon your Java loyalties lie, keep an eye on Eclipse and the RCP. This is not about windowing toolkits anymore.
June 08, 2005
Interfaces suck for public APIs
While coding against interfaces often makes for better design, publishing interfaces as part of a public API might put you in a world of hurt.
Imagine your application offered some kind of plugin architecture. You publish an interface Plugin which other people can implement and then use with the rest of your code. Your application becomes a wild success, with people all over the planet contributing plugins for fun and profit. All is great... until you think about writing version 1.5.
Suddenly you need every Plugin to implement an additional method getURI() and quickly realize there is no way of doing that without breaking the hundreds of contributed plugins in existence. Had you chosen to make Plugin an abstract class instead of an interface, you could just add a default implementation for getURI() that would, say, return the fully qualified class name as URI. But as you can neither replace an interface with a class without breaking binary compatibility, you're officially fucked.
When I was googling for this problem I found an excellent set of presentation slides from Jim des Rivières called Platform Quality APIs (260 KB PPT). It contains a lot of valuable advice for anyone wanting to write an API to stand the test of time. Since the presentation is unfortunately only available in Powerpoint format, let me paste in a slide called Use Java classes and interfaces wisely:
- API interfaces that clients do not implement are useful
- Excellent way to insulate client from implementation internals
- Allows there to be multiple implementations
- Adding methods in future is non-breaking
- API interfaces that clients may implement are inflexible
- Adding method breaks binary compatibility
- Abstract classes work better for this
- API classes that clients do not subclass are useful
- Use factory methods and hide constructors
- API classes that clients may subclass are useful, but difficult
- API frameworks are notoriously hard to specify
- Needs additional contracts for subclassers
Did I just write a "considered harmful" article? I never wanted to be like that.