Maintainability, Code Size & Code Complexity
The most maintainable codebase that I worked with grew at a rate of about ~10 KLoC per month, every month. There wasn’t a large team there, it ranged fro 3 – 6 people. This is the project that I think about whenever I had to talk about good code bases.
It is a WebForms project (under protest, but it is).
What make it maintainable? Not the WebForms part, which wouldn’t come as a surprise. What make it maintainable is that it is the first project where I had applied the notion that large swaths of simple code is better than smaller code base with higher complexity. You could see example of this sort of architecture in the Alexandria and Effectus applications.
Note: I am doing things like measure KLOC here mostly because it is a number that I can measure. As I am saying in this post, KLOC has very little to do with maintainability.
The
problem can be expressed well using the graphs. This is a
representation of the complexity of the application as it grows, lower
maintainability cost is better. 
The problem with the smaller and more complex code base is that the complexity tends to explode very quickly. With the larger code base, you end up more or less on the same plane.
But the above chart is somewhat misleading, because it make the hidden assumption that in both code styles, you’ll have the same amount of code, which is obviously false. Here is what is probably a more accurate representation of how much code is written for style per # of features.

This doesn’t look right. Not when we compare it to the chart above. Of the top of my head, I would expect the second chart to be the mirror image of the first one. But it isn’t. And the reason that it isn’t is that each feature you write still cost you some amount of code. And the rate of growth per features added is pretty constant either way.
Putting the two charts together, you can see that it means that even code styles with focus on less code in favor of more complex solutions grow, and that as they grow, they become less maintainable.
So far I have been very vague when I was talking about “complex” and “simple”. In part, this is because those are somewhat hard to define. There would be people who would claim that ORM leads to complex codebases, but I would obviously disagree.
For my part, I also strongly advocate of having a strong core of infrastructure that gives services for the rest of the application, and that tend to be complex piece of coding. But that is also something that is fixed, once the infrastructure is written, it tend to be static, so that saves you from the fate outlined above.
When I look at a piece of code, I do the usual evals (nesting, conditionals, cyclomatic complexity, etc), but I also look at how often the developers reached for a hammer and beat everything around to submission. There is a lot of gut feeling here. But I do have one objective metric to use to tell you whatever a piece of code fit either style.
In the fight between Don’t Repeat Yourself an Single Responsibility Principle, SRP wins, every single time.
Any time that I have seem code that did double (or triple or dozenile) duty, it led to the sort of “we have to write less code” style of coding that ended up in a quagmire.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Karl Pagan replied on Fri, 2010/09/10 - 2:39pm
"I also strongly advocate of having a strong core of infrastructure that gives services for the rest of the application" ... does that break the rules you set out?
And unfortunately this is sounds like a "golden hammer" - a framework or tool which can do everything. The tendency for any enhancement will be to creep into the walls of your framework rather than dealing with their problems directly.
Simplifying terms like "complexity" and "simplicity" into a LoC metric is practically meaningless. What exactly about this project was it that made it maintainable? Did you repeat yourself / copy-paste code? Was everything well described or documented by the code? Did you have a rich domain model? Many practices (both good and bad) can lead to high LoC. Similarly things like domain-specific languages, and tight code (trinary, inline if/else, cascades in switch statements) can produce low LoC as well as being difficult to maintain.
A good point to end on may be "why refactor?" or "do everything this way first, then get an expert to refactor after you ship" - that seems to be the best case to make based on your experience.
Cloves Almeida replied on Sat, 2010/09/11 - 11:03pm
Cost of maintenance has nothing to do with code size. It's related to "how fast can a second programmer understand the code", "how fast can a second programmer devise a solution to a given problem", "how confident is the programmer that the new solution won't break exisiting features".
We've built tools and techniques with just that in mind - compilers, checkstyle, automated tests, DI, ORM, web services, modularity. But I guess the problem is that is just too much stuff to adopt and it takes a while to we, developers, master it all.
Also, having a core infrastructure is a good idea as long you can reuse it for a number of applications. The problem that it's harder said then done - that's the central idea behind Java EE and just now we're beginning to do things the right way.
Liam Knox replied on Mon, 2010/09/13 - 9:55pm
in response to:
Cloves Almeida
King Sam replied on Fri, 2012/02/24 - 9:32am