Friday, March 14, 2008

Never Skip Curly Brackets

In the book that I'm currently reading the author continuously skips curly brackets where they are not needed. That is, in if, for, while etc. statements controlling only one line of code. I would have thought that all experienced software developers always used the curly brackets.

I can't come up with any reason not to use them, except maybe "less to type" or "less lines of code". Both reasons equally lame.

How much of your programming hours are spent typing? And whats the purpose to strive for less lines of code? The purpose must be readability, and I would not agree that it is increased by not using curly brackets. Rather the opposite. If your readability problem is caused by functions having many lines it is the design that is the problem, not the brackets.

Instead, not using curly brackets is very error prone.

Consider that you want to add something to the code block of an if-statement, now you'll need to add the curly brackets anyway. And if you fail to notice this it will cause weird errors in your program since the second line will always be executed.

if( foo )
foo = false;
bar = true;

Or lets say that you temporarily want to remove the executed statement with a comment. Now you'll need to add the brackets, or comment the if-statement too. If you don't do any of this the if-statement will instead control the next line of code.

if( foo )
//foo = false;

ASSERT(!foo);

As you see from these examples you may very well be fooled by the indentation of the code.

So, to all of you out there that aren't using those curly brackets unless you're forced too - start using them always!

Tuesday, March 11, 2008

Solving Bob's Problem

Reading up on Liskov Substitution Principle last night finaly put me over the top to start blogging about software development. I had a copy of Robert C. Martin's article published on the Object Mentor webpage (direct link) where he suggest that deriving Square from Rectangle violated LSP.

Here is his code example:

class Rectangle {
public:
virtual void SetWidth(double w) {itsWidth=w;}
virtual void SetHeight(double h) {itsHeight=h;}
double GetHeight() const {return itsHeight;}
double GetWidth() const {return itsWidth;}
private:
double itsWidth;
double itsHeight;
};

Sparing you the declaration of the Square class, which inherits Rectangle, here's how it differs. It overrides SetWidth and SetHeight, calling them both in the base class.

void Square::SetWidth(double w) {
Rectangle::SetWidth(w);
Rectangle::SetHeight(w);
}

void Square::SetHeight(double h) {
Rectangle::SetHeight(h);
Rectangle::SetWidth(h);
}

This will violated LSP since a client may call SetHeight with one number and SetWidth with another and presume that GetHeight will return what ever number SetHeight was called with - which will of couse not be the case.

He leaves us no solution in his article, so we're left to think that a Square never should inherit a Rectangle. I myself should in this simple case make the objects immutable. Aside from all other benefits it will also make the objects pass the LSP test.

class Rectangle
{
public:
Rectangle(double w, double h) {itsWidth=w; itsHeight=h;}
double GetHeight() const {return itsHeight;}
double GetWidth() const {return itsWidth;}
private:
double itsWidth;
double itsHeight;
};

class Square : public Rectangle
{
public:
Square(double side) : Rectangle(side, side) {}
};