Blog-Archiv

Mittwoch, 12. März 2008

Fashion

Clothings make the man. And fashion makes the clothes. In C that was spelled "I'm too lexy for my yacc". But nowdays we implement in Java. I'm too jlexy for my javacc?
Fashion seems to be not a real important thing compared to the excellent progress we make every day with our great applications. But it strikes, ultimately in code maintenance, which makes up to 70% of software production efforts.

Writing source code that makes computer systems available for human needs was always affected by fashions. Manipulating sourcecode by the C preprocessor was a special hobby of all experts. Out came things like MFC or MAPI sources, that sometimes even lacked the semicolon, until it didn't look like C anymore. In Java there is no more preprocessor, even when aspect-oriented languages took over, but these can not seriously be compared to preprocessors.

Nevertheless Java is affected by fashions like C was. Because it is practiced by so many people. Which is a good thing! I remember a fashion that put the fields to the end of the class, like some decompilers did. This looked like the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class TooClassyForMyFields
{
  public TooClassyForMyFields() {
    ...
  }

  // imagine several screens of big methods here ....

  private int id;
  private String name;
}

The compiler assembles this into the class file like the following (and the Java virtual machine reads it in that order, too):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class TooClassyForMyFields
{
  private int id;
  private String name;

  public TooClassyForMyFields() {
    ...
  }


  // imaginge several screens of big methods here ....

}

But we are not writing source code for the compiler, we write for human beings! So why should we keep that technical order?
That is right, never write source for the compiler. But sometimes the technical order is the same as human beings would prefer. When I'm reading a class, I am, in first instance, interested in the essence of that class, sometimes called its "state", the member variables that it keeps and hopefully manages to be always consistent. This models the relations to other classes, and gives a good picture what the class is about, or what is its target. So when I read the first lines, I get an impression that the class is about an "id" and a "name". After the fields I would like to get to know the public methods that form sort of an interface to collaborating classes. And, of course, any abstract methods, protected or public. When I need to derive the class, I might be interested in protected methods and fields. I am not interested in private methods, because I assume that they are working and running, so they can be on bottom of the source. Fortunately that fields-on-bottom-fashion was a short-termed one.
Besides: why is it cool to write fields at the bottom of a class?

But I'm not a fashion denier! Here are some of my favourite Java fashions:

  • Documenting source code. A nice class header, mentioning the target of the class. A heading comment for all public static final fields, and all public and protected methods. I do not like protected fields, but when they are not encapsulated, they should be commented.
  • Making long names. Writing name instead of n, and findObjectOrientation() instead of foo().
  • Inserting spaces after keywords: if (something) ... instead of if(something)..., or i += a + b instead of i+=a+b
Not popular? Not cool? Hm, that's just because they might smell of morality. But isn't that a sweet smell?
Seems that fashion always goes a little on the immoral side. So lets discuss it.

For example, there is a fashion I dislike particularly:

1
2
if (point.x == 1) builder.makeOne();
if (point.x == 1 && point.y == 2 || point.x * point.y < 5 || ......................./*soon out of sight*/...........................) builder.makeOthers();

Why?

  1. In prehistoric times, tools counted lines of code, which gave a little impression of what is under that project. Ok, we have abandoned them, nowdays we are using complexity analyzers instead (who does it?).
  2. When debugging that source I get no clear visual feedback when stepping over that two instructions. The debug pointer stays on the same line after the first step.
  3. When having a stack trace from some logfile, it contains the line number of TWO statements which could have caused the NullPointerException. I do not know if point was null or builder was null!

Fine, it keeps the source short and well-arranged - but not on maintenance. So i prefer

1
2
if (point.x == 1)
  builder.makeOne();

Besides, I found out a cool thing about assertions.

1
assert x == 0 : "X must be zero!";

When you write it like that

1
2
assert x == 0
  : "X must be zero!";

you can set a breakpoint on the second line and check the field values in the debugger if the assertion is about to be thrown!
Besides, this is my absolute favourite fashion: always write an explaining message after an assert!

Another thing is the good old "!" symbol from C. This is more than a fashion. It is a matter of course for a lot of people. I do not want to antagonize.

1
if (!condition.value)

can be written more readable as

1
if (condition.value == false)

It really makes it more readable, because it is bigger. Like long names are more verbose. We write for humans, not the compiler. And our machines nowdays have enough memory to process that all.

What about that:

1
if (((x instanceof MyClass) && ((b == 2) || (c == 3) || (e ==4))) || (allTrue() && noMatter()))

I mean the lots of parentheses. Now the discussion gets really hot. It is no doubt that parenthesizing the compiler preferences is nice for beginners that do not know that "&&" (AND) binds stronger than "||" (OR). But it lets take a short look at the short version:

1
if (x instanceof MyClass && (b == 2) || (c == 3) || (e ==4) || allTrue() && noMatter())

So what, do we like short code suddenly? Ok, I finish now.

We see that everybody has his/her own fashion. Writing source code is not objective. It is a little like a journalist's work. If it only was so easy. Writing, getting some fee for it, tomorrow being yesterdays papers, bothering nobody. But not on code maintenance!

Modern source code control and versioning systems provide the possibility to format each sourcecode that is checked in. The result is that the author revolts and insists on his/her coding convention, because it is easy to read for him/her, and he/she is working on that code. That is human, and it is not counterproductive (except on maintenance by other people, ahem).
So we would need a system that delivers a source to developer A in A's preferred style, to developer B in B's preferred style, ... and when they check it in, it is formatted to the project conventions again. Imagine checking in a big refactoring with hundreds of files ...
The other thing is that the versioning systems are still line-oriented. That means if you look for differences you might find all lines changed, just because someone formatted your beloved source to make it more readable. Readable for whom?

Fashion is nice if many people find a common sense in it for writing homogenous source code. Lets hope that fashions will go a nice way. The dominance of C* is over. The pain about the lack of a preprocessor is forgotten. Good times are rising. Give me hope, Joanna.


_____________________________________________________________________________________

Keine Kommentare: