Classic Development Mistakes

Throughout my career I’ve been involved in many re-write projects. I seem to consistently find myself in the situation where a company has a huge codebase that is 5-10 years old and they have decided to re-write it. The technologies are too old, the codebase is too messy and it’s too hard to introduce new features.

At my current position I was given the responsibility of keeping legacy codebase alive a bit longer by adding a few new features.

When I started going through the code I noticed quite a few patterns I’ve seen over the years. They all have the same motivation however.

1. Massive methods

Lots of developers seem to love to write very long methods. I saw one method recently that was 700 lines long! Each logical part of the method was separated by long comment blocks. Things like this:

/* ================================ SHIPPING PROCESSING ============================== */

I have to admit I have commited this exact sin many times early in my career. Why are there comments in the method? Why not just write a new method?

2. Enumerations everywhere

Legacy codebases always seem to have a lot of enumerations. In most cases I’ve seen the enumerations simply serve as a fancy way to replace strings so that code can branch. We want to carry around the enumeration so we can use it in an “if” statement or a “case” statement.

I see things like this quite often:

	if (StatusCode.Error && Request["..."] == "ABC") { ... }
	else {
		if (StatusCode.SemiOk) { ... }
		if (StatusCode.Ok && counted > 0) { ... }
	}

When used in a complex manner (like the one above), it becomes very tricky to debug. The developer that wrote this code just wants a “cleaner” way to reason about his objects and data. It’s easier to read in the IDE and “feels” better since there is intellisense.

3. Mega Classes

Usually when I open a legacy codebase I find a few very large classes. They are on average somewhere between 1,000 and 3,000 lines of code. They’ll have 30-60 properties. You can easily see that over time things were just added on as bug fixes and new features were introduced.

Usual suspects:

1. Some methods are static, some are not.
2. Some methods mutate other objects/classes.
3. Lots of checking of properties to see if they are null or valid. Often times this validation is repeated all over.

Conclusion

what do all these things have in common?

I believe the motivation behind these anti-patterns is organization. The developer wants to organize and structure their code and does the best they can with:

1. Comment blocks in big methods.
2. Enumerations that feel like they are categorizing things with intellisense.
3. Putting lots of code in the same place with mega classes. I’ve noticed the more object oriented a project, the more the classes grow in number, not size.

Classic Development Mistakes