Rodrigo Rosenfeld Rosas

How to write maintainable code?

Sat, 06 Aug 2011 08:37:00 +0000

I have been willing to write such an article for a long time and finally found some inspiration and time for doing it.

Working software does not suffice

No software is finished. Even Vi, which was created in 1976, is not finished. If no one is working in some software anymore it just means it is not being maintained or has been replaced by another one. That means your code will be changed or entirely replaced.

Unless you're expecting your software to be replaced soon, you should consider writing maintainable code. It's very important to your code to be readable and maintainable because most of the time developers will spend reading it. So, while knowing well your editor is important, you should consider spending more time refactoring your code to make it more readable than finding new ways of writing efficiently using your editor because a clean source code will save you much more time than any editor key mapping. But also, a good editor/IDE will also help you to refactor your code.

Continuous refactoring

You should really apply the good advices present in all books about Agile Software Developing since it is the only way I know of writing software that actually works in the real world. I'll not talk about Agile in this article, since it is out of the scope and there are also great books out there about this subject. I'm assuming that the reader is familiar with the subject though for better understanding this article. Here are the software writing guidelines that I'm talking about, although I won't explain the reasoning behind them, as they are a bit long and all books and articles on the subject will explain them:

  • Don't write code for the future
  • Write automated tests that cover your requirements
  • Continuous refactoring (will be extended in this topic)
  • Continuous integration
  • Continuous delivering

Since you'll be writing code for today's usage, sometime you'll face the situation where you need to write a new feature that shares lots of implementation details of a prior feature. You shouldn't be copying and pasting code from the prior feature. This seems obvious but if I didn't often find code written that way I wouldn't be talking about this. WARNING: whenever you find yourself copying and pasting some code, even for different projects, you should think twice. Most probably you should separate the common part in another method, class or library. Some languages will require some boilerplate code, but make sure you're copying and pasting only the necessary boilerplate if that's your case.

The commonest reason why developers don't rafactor their code is because they're afraid of breaking some critical production system. This is often related to the lack of a good suite of automated tests. Specially if your application is a critical production system, it should be covered by tests. The more you copy and paste code, the harder it will be to evolve the code base and understand it.

The same bug will also happen in multiple places in the source code and even if you fix it in some part of the code, the bug will show up again on Friday, 5pm, and you'll have to cancel your weekend planned schedule to work hard to find a hidden bug that was already fixed in other part of the code but you don't know that because you were not the one that fixed it. And people will be asking you why does it take so long for fixing the application under production in the most critical time where it shouldn't really fail while presenting it to a big potential client corporation!

Automated test writing

TODO: talk about test simplicity, coverage, documentation tool and careless about TDD or testing after. TODO: talk about test priorizing. TODO: talk about mocks and importance of speed and isolation of concerns

Keep your code minimal

You should really keep your code minimal to be polite with the other developers that will work in your code some time later. Maybe that developer will be you again. Having small methods, classes and files will help reading the code without the need of scrolling the text. Also, some editors like Vim allow you to display multiple source files at the same time. Having small methods will help you to understand the overall code.

Naming

TODO: talk about spending time thinking in good names

Avoid comments

TODO: talk about how comments can be avoided with clean code

Choose a good language if possible

TODO: Compare C++ and Java to dynamic languages like Ruby, Python or Groovy TODO: talk about tradeoffs and performance concerns vs development speed TODO: talk about legacy Java code and JRuby, Groovy, Scala, Clojure and JPython. TODO: also talk about network-based API integration

Adopt great frameworks and libraries

TODO

Upgrade often

TODO

Keep It Super Simple - the KISS principle

TODO: Avoid uncommon solutions and complicated architectures

Avoid proprietary or language-specific solutions

TODO: Give preference to common network based APIs

Understand the Single Responsibility Principle (SRP)

TODO: you can apply or not but it's important to understand it

Don't bother too much about the Open/Closed Principle (OCP)

TODO: explain differences between writing end-software and libraries and talk about tests here

Take decisions by yourself (avoid just following well-stablished patterns)

TODO: talk about Java, setters/getters, private/protected/public, interfaces and its abuse

Use dependency-resolving tools

TODO

Use the best VCS tool you can find

TODO: and invest time learning it

Coding style examples

Early interruption pattern (or handle exceptions first)

TODO: return if exceptional_case

Don't handle exceptions at all if possible

TODO: talk about the try-catch approach and the type of applications (libraries, unsaved data) as well as about tests.

Don't catch each exception for general algorithm

TODO

Avoid deeply nested constructions

TODO: talk about nested if's, while's and alternatives like catch-throw

Sort method caveat

TODO: talk about <=> and how to deal with its lack in some languages. Sort should return -1, 0 or 1. TODO: talk about wrong usage of sort for getting max and min.

Switch-case and handling by hashes (or maps)

TODO

Security concerns

Mass-assignment

TODO

Multi-threading

TODO

Java specifics

TODO: talk about synchronized methods

Performance and Scalability

TODO: talk about language vs architecture, and concerning before due time or without benchmark/profiling.

TODO: talk about simple web APIs and queuing systems for integrating applications in possibly different languages. TODO: Avoid writing language or vendor specific solutions

Memory leak

TODO: It does happen in Java. Talk about unbounded in-memory cache.

Powered by Disqus