I used to think I knew what this was, until I really started thinking about it... "maintainable"... what exactly makes code maintainable?

To me, if code must be maintainable that means we can expect to revisit the code to make some sort of change to it in the future. Code is always "changeable" no matter what state it is in. So does this mean code needs to be easy to change? However, if our code was scalable/extensible, there would be no need to directly change it, because it will "change" (adapt) for free and automatically.

I've also seen code maintainability used interchangeably with coding standards. Using a consistent coding pattern or style, does this really make code more maintainable? More readable and more consistent? Sure, but how does this improve the maintainability?

The more I try to think into this, the more confused I get. Anyone have a proper explanation?

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3

You may get some insight from this question as well as this one.
– BernardFeb 13 '12 at 19:29

@Bernard: Thanks. I did read the latter one already, but it isn't specific enough. For example, when I hear someone talk about code "elegance", I know that means the code is probably simple, compact, and easy to read. Probably follows the KISS principle. When I hear someone talk about how their code is maintainable... uh... I kind of draw a blank on the real exact meaning of what they are saying.
– void.pointerFeb 13 '12 at 19:32

4

Simple test: If someone else can read it after 6 months and make sense of it in less than 5-10 minutes, it's maintainable! :)
– PhDFeb 13 '12 at 19:34

1

So then my definition would be: "Simple, self-documenting code that is pleasant to revisit". Does that about sum it up?
– void.pointerFeb 13 '12 at 19:37

9

@Nupul, even simpler test: if you, the author, can read it after 6 months and make sense of it in less than 5-10 minutes, it's maintainable! :)
– Péter TörökFeb 13 '12 at 20:48

11 Answers
11

Maintainability isn't a binary property, either being maintainable or not. It's a continuum. Roughly speaking, maintainability is inversely proportional to the amount of time it takes a developer to make a change and the risk that change will break something. Improving readability, coupling, or consistency all contribute to maintainability because it won't take as long to make any given change. Maintainability is easier to recognize by its absence, like when something you thought should take an hour ends up taking a week.

Coding standards help in that your code base should be consistent, therefore easier to grok than a code base that contains multiple coding styles. Something that's easier to understand is easier to maintain.

To me, maintainable code really means code that reads like a book and is well documented.

Maintainable code is unit (and functional/integration if needed) tested so that if a change is made that introduces a knock-on effect, it's caught quickly and early, before the code's even checked in.

To me, maintainable code doesn't take advantage of quirky language features that 0.1% of the programming population is aware of (i.e. simple example: using an XOR swap instead of a temporary variable just because the author thinks "it's cool".

I understand most of the points, except for your last. I'm a C++ developer, so my equivalent "quirky" feature would be template metaprogramming. I agree that code like this spread everywhere definitely hurts the ability to understand it and make quick, easy changes, but sometimes "quirky" code is necessary and unavoidable, so we do our best to hide it away under nice, maintainable interfaces and abstractions. Does this still go against the principle of having maintainable code?
– void.pointerFeb 13 '12 at 19:35

3

@RobertDailey When used appropriately template metaprogramming is not a quirk.
– KarlsonFeb 13 '12 at 19:39

@RobertDailey: Agreed (sometimes it's necessary). As long as it's documented, then it's fine. I also agree with Karlson.. When used appropriately, it's not a quirk :)
– Demian BrechtFeb 13 '12 at 19:41

2

@RobertDailey: "Read like a book" does mean self-documenting code, but as you pointed out, there may be numerous times throughout a codebase that, due to the specific problem, tricky code may need to be written, in which case it should be well documented.
– Demian BrechtFeb 13 '12 at 19:58

4

@jmort253: Jim Larson on comments: "If you do something clever, brag about it. Not only will this inflate your ego, but it will also subtly tip off others as to where to look first for bugs." link
– ruakhFeb 13 '12 at 23:39

Code maintainability is the synergy realized when we apply all those coding axioms, rules of thumb, principles, etc. It is more art than science. To the extent that we have cooked in an appropriate amount of all these things, the code base is maintainable. Code is not maintainable (yes/no, on/off, either/or) just because you are able to change it (or not).

However, the acid test of maintainability is attempting to change the code. To the extent that the code resists, or doesn't resist, your interaction with it defines it's maintainability.

Maintainability has "abilities". Including, but not limited to

readability

understandability

changeability

testability

reliability

others?

How do we attain these abilities?

Through application of all those software principles and guidelines you've ever or maybe never heard of. For example:

Good comments

descriptive variable, method, class names

Limit methods to no more that a page in length

Maximize cohesion and minimize coupling

encapsulate that which stays the same

encapsulate that which changes

code layout/formatting guidelines applied consistently

One entry point only, and one exit point only.

... and many, many, more ...

For good maintainability one must consider all of them, all the time, at every level of the code, and apply them in an (not "the") appropriate mix. Further, and I cannot emphasize this enough, no principle works best (or very well at all, perhaps) alone.

Seek Your Roads To Damascus

Several years ago two things came together. A set of programs that were literally unmaintainable and my discovery of Code Complete by Steve McConnell. This book was my bible in rewriting all that worse-than-failure code and the "before and after" comparison of the code was nothing short of revelation.

Find your roads to Damascus. It's a target rich environment.

Read Code Complete

I cannot overstate just how good this book is for learning fundamental software development principles.

@PéterTörök, I'll see your thread reference and raise you every COBOL program I've ever seen. However, That thread illustrates a basic C++ idiom for coding a very simple test-and-return; and is fine as far as that goes (and it complies w/ the "one entry" half of that guideline). You'll also see immediate returning with input parameter checking - and when the alternative is a 40 line "else" statement, that's fine too.
– radarbobFeb 13 '12 at 21:33

Maintainable code is code that exhibits high cohesion and low coupling. Cohesion is a measure of how related, readable and understandable code is. Coupling is a measure of how related code is, low coupling means that changing how A does something shouldn't affect B that uses A. Generally lower coupling means lower cohesion, and vice versa, so a developer need to find an appropriate balance between the two.

Maintainability is itself a measure of the ease to modify code, higher maintainability means less time to make a change. Coding standards are a way to achieve high maintainability and are developed as a result of previous experiences, they aren't universal and are dependent on developer preferences.

Ask yourself some questions.
(or, as some may say, let's run together trough some scenarios)

How hard will it be for you to understand what you wrote?

Last week?

Last month?

Last year?

27 years from now?

How hard will it be for a coworker to understand what you wrote?

In the unfortunate event everybody on your team is unavailable, but a fix must get trough in hours, and the only guy available for the job is a summer intern, how likely is he to succeed?

And then:

how hard will it be to apply a security fix to a random chunk of code?

how hard will it be to change a logic misunderstanding of the requirements?

how hard will it be to take care of usability/UX/cosmetic issue?

how hard will it be to adapt to the ever changing legal landscape?

how hard will it be to push some new marketable features in?

how hard will it be to port the whole thing to a different architecture?

And the best of all:

how hard will it be to adapt the whole behemoth to a new set of requirements for a client with a similar needs, but...?

This is more or less what maintenance is about.
The latter is more about transforming the application into a product,
maybe, but that's a need that's pretty typical to raise, with time.

"Best Practices":

Comments

Documentation

Diagrams

Consistent indentation

Coding Patterns

Are all just meant to make your code survive longer.

Coding patterns, in particular, help maintenance by making code reading less and less of a discovery, and more and more of a "Oh yeah, I saw that already, so the part I'm looking for should be... around here".

They should, obviously, be used with caution and never be copypaste/abused just for the heck of it.It's not LEGO, it's more of a source of inspiration.

Chances are if you cannot relate someone's usage of some pattern with advantages in maintainability, they are not using them right. But stay assured that as a way of comparing different solutions and permitting faster response times in case of maintenance, they are theoretically sound.

I am surprised that no one mentioned McCabe complexity metrics. A high complexity metric is a real code smell when it comes to maintainability. It's sometimes necessary for a routine to be "complex" but usually indicates code which will be really hard to maintain.

Looking at this another way, All code is maintainable. The differentiating factor boils down to the effort required to maintain the code and the amount of technical debt the code represents in any given state.

Well factored code requires little effort to maintain, and when you do need to modify it will not impose a significant resourcing cost. Code that is difficult to read, too "clever" for its own good, poorly factored, or which does not suite the intention for which it was written, these are the types of code that incur higher costs to maintain, or to work-around if the cost:benefit makes it more expedient to avoid direct maintenance. Failing to maintain poor code greatly increases your technical debt, and increases the likelihood that the code will eventually be considered too costly to maintain.

Labeling code as maintainable vs un-maintanable can result in significant losses to your company, and can result in the stigma of project failure following its developers around like a bad smell for years. Changing the language to be more about effort, and less about the perception of maintainability can be more useful in the longer term, by helping to focus efforts on the problem before it becomes very difficult to manage.

When working with other developers who need assistance in understanding what maintainability means, I will ask them, "If you application crashes at 3:00 AM and you get called out of bed to fix it, is this code you would want to look at then?" You'd be surprised how this can change people's point of view.

maintaining code means taking that code and making a change to it to fix a bug or add a feature

maintainable code makes this process easier

making code maintainable means making it easy to understand (descriptive variable names, comments and documentation will help here) and making changes to it easy to make (patterns can make this easier, but it depends on the actual need)

I have defined maintainability as: a measure of the effort required to change the functionality of application software. A measure of ‘effort’ must include time, resources and expertise.

In general any software development manager is familiar with this definition of ‘effort’ as it applies to creating software. The term ‘change the functionality’ applies to both enhancements as well as bug fixes. It might also be said that maintainable code is designed to be leveraged.

It does take some effort to create maintainable software. For what it is worth, I recently started a blog on the subject.

Maintainable is - to some extent - subjective. However, it's code that is written less with the writer's ego in mind and more with the recognition that at some point, someone is likely to have to revisit this code and modify it for reasons currently undefined. Very few codebases stay static for years on end.

What one person considers maintainable may be very different to another's view in some respects but some qualities I think it should include are:

no hidden traps for the unwary in the future

logic and rationale should be documented

it should conform to some documented local standards

We have discussions here on the subject of documentation and commentary from time to time.

Code whose remit and logic is easy to follow should for the most part be easy to update as required with some caveats on original design considerations (which should be but ime never are documented adequately).