Saturday, April 11, 2009

Decreasing maintenence through formatting

How important is formatting to the development process? Is aligning function names with tabs important?

It's startling how much a difference a little white-space can make in the readability of a header file. Here we have the identical class in two different scenarios. Notice how much quicker the class on the left makes sense to you and how much more quickly you can assess it's usefulness to you. As a quick test, look at the class on the right... does it allow networking? Does it write to a database? Now look at the class on the left... does it render? Which member variable stores position?

If you try to answer the questions posed above, you will find that the class on the left is almost instantly interpreted and almost a brain-dead exercise. The class on the right is almost excruciating to read. Now you might think that no programmer on Earth would ever write the code on the right, but sadly, you'd be wrong: just a few weeks ago, I ran into this exact scenario where I was put in charge of similar, nightmarish code and told to not make any changes. This example isn't even long, around 30 lines where the code I had was over 80 lines.

Without color highlighting, this situation is slightly harder for reading both cases, but in many cases, all types will be types internal to the company and thus color highlighting won't be displayed.

By aligning all functions as I have done on the left, much like you would see in a spreadsheet program (or a phone book), you can easily ascertain the functionality of this class. This dramatically improves the time to find the "right" class to do the work you need. While this doesn't affect the experienced programmer who knows the code base, new hires become almost instantly productive. Studies in code reuse and programmer productivity (HP, IBM, MS, et al) have all shown that well-aligned code can increase programmer productivity in general, not just for new hires. The extra white-space in between functions and between functions and their return values makes a huge difference. I would suggest that both are about the same in importance.

Please, for the sake of all programmers who follow you, including yourself, follow the white space example on the left.







//------------------------------------------
class AI_Bot : public StellarObject
{
public:
AI_Bot ();
void Clear ();

BotState GetBotState () const;
BotTarget GetBotTarget () const;
UUID GetPlayerTarget () const;

//---------------------------------------

virtual void Setup ();
virtual void Draw ();
virtual void Update (GameData&);

//---------------------------------------

protected:

bool CheckForTransition () const;
void BeginTranition ();
bool IsInTransition () const;
void ResetState ();

void UpdatePosition ();
void IsPossibleToInterruptCurrentState ();

BotState myState;
BotTarget myTarget;
uint32_t timeOfLastStateChange;
BotState transistioningState;
UUID playerTarget;
Vector destination;
SpaceStation* baseDestination;
SpaceStation* homeDestination;
BasicProjectile* selectedWeapon;
};

//------------------------------------------


//------------------------------------------

class AI_Bot : public StellarObject
{
public:
AI_Bot();
void Clear();
BotState GetBotState()const;
BotTarget GetBotTarget()const;
UUID GetPlayerTarget()const;
virtual void Setup();
virtual void Draw();
virtual void Update(GameData&);
protected:
bool CheckForTransition()const;
void BeginTranition();
bool IsInTransition()const;
void ResetState();
void UpdatePosition();
void IsPossibleToInterruptCurrentState();
BotState myState;
BotTarget myTarget;
uint32_t timeOfLastStateChange;
BotState transistioningState;
UUID playerTarget;
Vector destination;
SpaceStation* baseDestination;
SpaceStation* homeDestination;
BasicProjectile* selectedWeapon;
};

//------------------------------------------

No comments: