Safer Java: Think Positive

2. February, 2008

If you’ve ever developed software for X11, you probably stumbled over “unmap”. For everyone else: If you wanted to make something in a X11 user interface visible, you’d set “unmap” to “false”. A great way to interrupt work because we’re not used to negative thinking. If I want to make something visible, I think “I set some attribute to true” not the other way round.

In Java, we have learned but some API still smells. Collection.isEmpty(), for example. With positive thinking, I think of collections with elements as “better” than one without, so I’d prefer Collection.hasElements() even though it’s longer and boolean properties should use “is” instead of “has”. Oh well. But it’s simple to fall for the negative trap in your daily work as well.

If you find yourself stumble mentally when using a boolean API, refactor and turn it positive. Modern IDEs make this simple and you’ll write more error-free code in less time. commons-lang offers isBlank() and isNotBlank for Strings which is a good example because you don’t have to put a “!” negator in your if’s no matter if blank is good or bad in your specific case and the JIT will inline the code anyway, so there isn’t even a speed penalty (only a LOC penalty).


Safer Java: No Pseudo Constants

24. January, 2008

Even the pros do it: String “constants” i.e. a string literal (that is something between ” quotes) used as a “constant”.

That’s almost as bad as using integer values as arguments instead of defining symbolic names for them! I mean, the values passed into this API are defined by the standard, aren’t they? Sure, you can pass additional feature names as well but that doesn’t stop anyone from defining those which the standard defines somewhere! So what that not all of them must be supported!

There are several reasons why you should always define string constants when your API need strings as parts of it’s “configuration”:

  1. It makes it much more simple to find possible values for your API.
  2. Auto completion in an IDE is possible and helps to avoid typos.
  3. You can add JavaDoc to your strings explaining what they do.
  4. Modern IDEs can find out where your strings are being used in the project.
  5. You can rename the constant and change the string value, even if you have several constants with the same value!
  6. Even if the literals are read from a file, still define a constant for the string and map the raw string to the constant as soon as possible. It makes it so much more simple to track!

Tip: If you still use Java 1.4, define your string constants in an interface (without any other methods). That allows you to use “implements” anywhere where you want to use the constant names without having to prefix them with the name of the interface:

public interface Constants {
    public final static String A = "a";
}

class Demo implements Constants {
    private String value = A;
}

With Java 5, you’ll use enum, of course (especially because you can then use these “strings” in switch statements.


Safer Java: Constants First

22. January, 2008

Here is a simple change in your Java development style that will save you a lot of time: When comparing something against a constant, always put the constant first. Examples:

    if (0 == x)...

    public final static String RUN = "run";
    if (RUN.equals (mode))...

That will look strange at first because we’re used to have the constants on the right hand side (from assigns). So what’s the advantage of this? There are three:

  1. It will save you a lot of NullPointerException when using equals().
  2. It’s more readable in big if/else “switch-alikes”, when you compare a variable against a lot of values.
  3. It avoids the accidental assignment as in if (x = 0) (which should have been if (x == 0) … and if you can’t see the difference between the two, you really should always do it this way!) because if (0 = x) generates a compile time error.

Try Git

31. December, 2007

I’m not cutting edge. I was a long time ago but today, I prefer mature stuff. That’s why I cultivate the luxury to ignore brand new, cool software until it’s not only cool but most of the wrinkles have been ironed out by those guys who like to bleed (it’s not called “cutting edge” for nothing).

So when Subversion came out, I stayed with CVS until version 1.2. I installed it and liked it immediately. Now, some years later, even the Eclipse plugins (Subclipse and Subversive) work so well that using them becomes uninterruptive.

The same is true for GIT. When Linus (of Linux fame) announced it, I knew that this guy was probably smart enough to know when to start a new version control system and when to stay with the flock. Alas, I never had the pressure to try it.

Actually, I had the pressure but I didn’t notice because I didn’t know enough about GIT, specifically what it does different than, say, Subversion (a.k.a “the worlds largest patch for CVS”). In nutshell, GIT is a set of commands to manage one or more repositories with the same or different versioned objects.

Confused? An example: You work at a paranoid company that won’t allow you to connect to some OSS CVS/SVN server to update the files of a project which you’re using in your daily work. Sad but quite common. Let’s ignore for a minute the relative dangers of using CVS (which you aren’t allowed to use) and using HTTP (which you can use). What options do you have?

You can download the files at home, put them on a USB drive and take them to work. That works pretty well. Now, one day, you make a change to the sources at home and at work. Only, you forget to commit one of them. So you keep updating the sources and eventually, you will run into problems merging the files because of that one uncommitted change.

This happens because neither CVS nor SVN allow you to “clone” the source repository. GIT works differently: When you start, you either create an empty repository or you copy an existing one. When you do that, you get everything. If that other repository gets corrupted, it could be restored completely from your copy. (Remember? “Backups are for wimps; real man put their software on public FTP servers and let the world mirror them!”)

Also, GIT will track the work in each clone repository in an individual branch (unlike SVN where everyone usually works on the same branch). When you checkout the latest version in your working directory, you don’t work on the same branch as any other developer. If you commit something, that’s in your local branch only. If you break something, no one but you will notice.

Only when you’re satisfied with your work, you “push” your changes over to other people. You needn’t even push it to everyone at once. You can send your changes to a few colleagues first, before pushing them to the main project repository for everyone to see. Or you can keep it. GIT will happily download all the branches from the main repository without disturbing yours unless you say “Hey, I want to merge to main development into my code.”

At that time, you will notice something: GIT will ask you to commit all your work first if you have uncommitted files in your working directory. In SVN this isn’t possible or at least not that simple; you’d have to setup a SVN branch for each merge you do. For GIT, it’s simple because from its point of view, the changes are not related in the first place. True, the do have a common ancestor somewhere but after that, they are as independent as they can be.

So you have the great luxury to be able to commit all changes you made, saving all your work before you do the actual merge. You can even save stuff away that you don’t want to merge, so every modified file after that is actually part of the merge. This also means if something goes wrong, you can simply roll back all changes by checking out the head of your local development branch. Even better, you can create better diffs. It’s simple to create a diff for a) everything you changed (diff common-ancestor local-branch-head), b) everything everyone else changed (common-ancestor global-branch-head) and c) everything you changed to do the merge (diff local-branch-head working-copy). In SVN, you usually see a mix of a) and c), at least.

So, if you usually work from several places and can’t keep a network connection to the central server all the time, give GIT a try when you start your next project. It’s worth it.


The Elevator Problem or Why Writing Software Is So Hard

2. July, 2007

A lot of people wonder why writing high quality software is so hard. When you read this, you’re probably sitting in front of a computer that runs an operating system with millions lines of code. Most people know that a computer “computes”, that is it adds numbers all the time and because we define some numbers to mean characters (65 usually means A) or colors (0 is black, 16777215 is pure white, 16711680 is bright green, etc), it can do astonishing things. Like showing you something a guy on the other side of the globe wrote. It’s all just math.

As we all know, math isn’t simple but 1+1 always gives 2. It doesn’t sometimes give 1.9 or 2.2 or 3 or 1. It’s 2. Always. That basic observation made many people believe that it must be simple to write correct software. It’s just math, after all. It’s exact. Well, let me tell you a story so you understand why writing software is so hard and sometimes insane.

Imagine you’re working in a big company. Your company is so big, it has its own skyscraper. There are six elevators that carry all your co-employees in and out, every day. This morning, your boss storms into the room and he’s obviously very upset: For the third day in a row, someone is using his parking lot. You say, no problem, you’ll put a sign in the elevators that the parking lot #5 right next to the elevators is reserved. Your boss is very happy and you can see the next raise shining brightly at the horizon.

So you turn to your computer, fire up your favorite text tool and after a few minutes or hours (depending on the tool), you come up with a nice sign saying to stay the hell away from parking lot #5. A few minutes (or hours) later, your printer has delivered the signs on nice fresh paper. You grab ’em and walk to spread the news in all six elevators. It’s the most simple thing in the world to press the button to call an elevator. You wait a few moments (or longer, it’s a big building) and “bing”, one of the six elevators stops by to get you somewhere.

You smile, step into the cabin and slab the first sign onto the wall. You brought Scotch tape, right? Of course you did. And scissors, too.

The sign looks great. Your boss will be very happy, he will think fondly of you when it’s time to spread the good stuff.

So you leave the elevator, let’s call it A, wait for the doors to close and press the call button once more.

“Bing” and the door of elevator A opens, so you can take the ride. You start to realize that this simple task might not be that simple after all.

There is a little computer somewhere in the building, that tries very hard to move the elevators around effectively and right now, it’s very proud of itself because you didn’t have to wait. Now, it eagerly waits for you to tell it where you want to go, so it can take you there as fast as possible. In the meantime, it does the same thing with the other five cabins.

After pondering the situation for a moment, you step inside the cabin and press the button of the floor that is farthest away from where you currently are. The door closes, you wait a moment, so it is really gone and call the next elevator.

“Bing”, elevator A opens it’s door again.

Apparently, it hasn’t moved at all or it can move much faster than you’d think possible. Let us rule out the second option because it probably breaks some laws of physics. You do know that elevators measure the weight of the passengers, don’t you? Well, some time ago, smart engineers noticed that kids wasted a lot of energy sending the empty cabins around. That made them angry, they didn’t want little pests to toy with their toys. So they used the very same sensor to determine if someone is actually inside and if not, they told the little control computer to just ignore any requests to send the elevator around. Ha! That shows them!

All right, you tell yourself, and go for the staircase to move a few floors down. Slightly annoyed, you press the call button. You wait, “Bing” and … elevator A offers it’s service. Somewhere in the house, a little control computer is very proud that it could send you an empty ride so fast.

Now is the time to start to worry. You could ask your buddies in the office for help. You need five of them, each rides one elevator to some floor and blocks it there. Of course, you know them and you’re a bit worried about the remarks you’ll probably get before you can explain to them why on earth it could be so hard to stick a piece of paper on an elevator.

Now is also a good time to think what you boss will think when you don’t return soon. Surely, to stick six pieces of paper on a wall can’t take more then a few minutes? What will he think if you fail even such a simple task?

The morale of the story: Even very simple things can become insanely complex as soon as a computer is involved. Unfortunately, even seasoned developers with years of experience sometimes fail to see all the traps in advance. That leads to the paradox situation that they concentrate on all the “hard” stuff, which they expect to cause trouble and postpone the “easy” stuff. If that easy stuff is hiding a bad surprise, it’s usually late in the project when you finally get to it. And at that time, the effects might be tremendous because you made your all your plans and estimates with the idea in mind that the “easy” thing will be a cinch.

That leads to the conclusion that it is impossible to estimate a software project except you have done the very same thing (including all circumstances!) before, preferably several times. If you didn’t, your estimates are just guesswork and could be off by several magnitudes (i.e. 10, 100 or a 1000 times).

PS: The solution for the elevator problem is to find the janitor or someone from the cleaning team. They have keys to take cabins out of service (ever noticed the locks near the buttons? That’s what they are for), so they can clean or repair them. Or you could paste the notice on the wall next to the parking lot. Or place one under the wiper. But we’re computer freaks; simple solutions are for wimps!