One of the measures of maintainable software is its acceptance of changes later on by developers other than the one(s) who wrote it. But what characteristics does software have when it has been in production for awhile and the client wants a new developer to add a feature or fix a bug? What activities, attitudes, techniques, and/or practices contribute to software being "maintainable" 6 months later?
-
2Note: after 6+ months, it probably doesn't matter whether it's the original developers or others that are trying to change the code. – Jörg W Mittag May 03 '15 at 01:51
-
1Actually I think this is a great question that should be asked and answered by all professional programmers. One-off cruft for fun or a class assignment is one thing, but long-lived production code needs to be treated as such from the beginning. Since answers are currently blocked I'll toss one more item into the fire: 10,000 foot documentation. This is a brief, concise description of why the program is being done, followed by slightly lower elevation docs on why particular approaches/algorithms were chosen over others. 6 months/years from now that reasoning may aid/prevent a rewrite. – Peter Rowell May 03 '15 at 17:44
2 Answers
Automated testing
A comprehensive suite of automated tests is perhaps the most useful feature of a code-base when it comes to enabling someone with no prior familiarity to make substantial changes.
Usually when entering a new code-base you have low confidence that changes won't have unintended effects, so you start small and as you become more confident in your understanding of how the system works you make bigger changes.
Automated testing can really speed up this period of confidence building by ensuring you have the same understanding of what "correct" behaviour is, and that you haven't deviated from that.
Self-documenting code
External documentation and code-level documentation is great, but often it's a band-aid solution to code which is difficult to read.
Prioritise making your code easier to read, then if that's not enough consider where additional documentation would help.
Typically a high level system description or overview to find which code to start reading is helpful, but even then naming your directories and files so people can easily guess where things are is preferable.
Reliable automated build tools and dev environment
Make sure the process to get started developing on the code-base is quick, automated and reliable.
This particularly applies to running the application - don't make them have to update 10 different paths or click through 20 different IDE menus just to get it running, and make sure they can easily match the production environment.
No matter how good your instructions for building or deploying the project are, automating as much as possible for them will save the very likely possibility of someone new missing a step.

- 1,155
In addition to existing answers, I would like to add:
Being simple, small, well-defined and limited.
Justification:
When each of these descriptions are negated and applied to a piece of software, it will imply an increasing difficulty of understanding its source code.
Being modular, and conforms to (1) LSP as well as (2) POLA.
These are the necessary (but not sufficient) conditions for preventing what is known as leaky abstractions.
Leaky abstractions are unavoidable, but violations of modularity, LSP and POLA will increase the amount of details that software programmers must juggle with when working with the software, thus increasing the mental burden.
The coding style is familiar to the programmer.
Justification:
This lowers the learning burden on the programmer.
The code is highly navigable.
Given task:
The customer would like to make a small change to a software feature. The customer describes the change request, using terminology and mental models which the customer has learned from the user interface. The software programmer must now figure out the different parts of source code that corresponds to what the user has described.
Evaluation criteria:
The terminology, mental model, and organizations of software features are highly similar between the user interface and the application source code. Furthermore, the source code is organized according to well-established software application architecture principles, which speeds up the programmer's understanding and navigation to the relevant parts of source code.
The software is traceable.
Given task:
A customer discovers a bug in the software that can be triggered when the user performs a sequence of steps on the user interface. Please investigate and fix the bug.
Evaluation criteria:
For a software application to be traceable, a programmer must be able to trace out its execution when the user performs a sequence of steps. It is hopeful that once the execution has been traced out, a follow-up investigation on the execution path will provide clues for the root cause and a resolution to the bug.
Typical ways to achieve traceability:
- Tracing / Logging
- Being compatible with debuggers
- Writing out execution snapshots so that the software's internal states can be examined.
- Built-in software code that can verify its consistency of states during runtime.

- 16,878