5 steps to more maintainable code

Updated

For the last seven years majority of my work has been related to Android development. During that time I’ve read, written and reviewed code that has been everything between superb and just awful.

As I’ve worked on different code bases, plowed through the rough patches and marveled the best parts, I’ve noticed that there are few a things that are always present in successful projects.

In this post I’ll go through my findings, explain how they work and how they make your code better. Although my findings are inspired by Android development, the steps I present here are universal. You can use them to make your code better even if you’re not working with Java or Android.

Write less code

The fastest, easiest and for some reason often neglected way to improve the quality and readability of your code is to have less of it. The less code your repository contains, the easier it is to understand and grasp the whole picture.

When working on project, one of the easiest ways to reduce the size of your code base is to implement common repetitive tasks with the help of libraries. By using libraries, instead of needing to maintain more code yourself, you include code that is maintained and tested by others. This especially holds true if you use libraries that are seen as industry standards.

For example, you don’t need to implement your own network communication code, there are lots of libraries that will do that for you. The added benefit of using a library is that, if you choose a well known industry standard library, the code is tested by the developer and by other users. So most probably the library code has fewer errors and bugs than the implementation you would write yourself.

Comment your code

The easiest way to make your code more readable and understandable is to write comments that clarify what the code is doing and why. Unfortunately commonly the code bases are not commented or if there are comments, they’re either very light on detail or not true anymore due to refactorings.

One of the arguments I constantly hear against commenting code is that the code base is changing so rapidly that it’s a waste of time to keep the comments up to date with what’s happening in the code. In my opinion that’s just an excuse, comments should be seen as equally important as the code itself. And they should always kept up to date the same way as the code, not something that’s updated when there’s time or energy.

One of the most obvious issues that uncommented code brings is that it takes a long time to understand what’s happening and why. Also sometimes it’s impossible to know what should be happening if the developer hasn’t written down the original idea in the comments.

Use the right tool for the job

In addition to reducing the size of your code base and commenting the code you write, it’s equally important to use the right tool for the job. When talking about Android, this means using the right classes from the Java standard library as well as using the right libraries to get the job done.

For example far too often I see experienced developers making novice mistakes when working with Java collections. There’s a time and place for using a List, Set, Map, Queue, Vector, Dequeue etc. As a developer it’s important to know when that time and place is.

I’ve seen numerous times code that makes sure a List instance doesn’t contain duplicates. But instead of doing that, the developer should have used a Set instance in place of List that handles the duplicates automatically.

In addition to Java standard library, there are also many nifty helper classes included in Android. Classes like TextUtils, SparseArray and LruCache. Using these classes, which are specifically created for Android’s use cases, can improve your applications performance and minimize memory consumption.

The downside is that there’s no guaranteed nor easy fix for this kind of usage of the wrong classes. Developers should always try educate themselves either by reading about different solutions to problems or working with senior developers who have encountered these same problems earlier.

Architect your code

Over the years I’ve noticed that the single most important part of good code is good architecture. Good architecture makes the code easily understandable and allows further development without requiring massive amounts of refactorings.

The most difficult part about architecture is that there isn’t any single right way to achieve it. Architecture depends on the project at hand, what works in one project doesn’t necessarily work in others. But there are some guidelines that I’ve noticed to help when working on project architecture.

First of all, different parts of the projects should be kept in meaningful packages. That is UI code should have it’s own package(s) as well as business logic and data persistence. Now when different parts are separated it’s easy to limit the visibility of classes, methods and variables to the bare minimum required to get the job done. For example data persistence package shouldn’t reveal on how the persistence is achieved, only the methods to use the feature. The same applies to every other package in the app that provides some kind of a service to others.

Separating the app to different parts makes code refactoring easier. When you keep the publicly visible interface the same, you can change the underlying implementation easily. Since the interface stays the same, you don’t need to make changes to any other parts.

This can also be viewed from a different angle, when a new developer joins the project, it’s easier to get up to speed with the development when it’s clear what different parts of the code does. This separation bundled with good documentation makes it easier for new developers to join the project.

Google provides great samples of different kinds of Android app architectures at Github, I suggest everybody to clone the repository and check the different architectures out.

Check for errors

When we’re developing our apps, we make mistakes and potentially add new bugs every time a line is changed. It’s unavoidable since we’re all human. But we can reduce the amount bugs and errors by using automated tools to catch them.

One of the best ways to make sure your code works as it’s supposed is to write tests for it. Tests, as the name implies, test your code and validate that it works the way it is designed to. Writing tests requires time and dedication which unfortunately leads to the fact that tests are often not written at all or they’re neglected after the initial implementation.

In addition to written test cases, there are other tools that help you find bugs in your code. Static code analysis tools, like FindBugs, check your code base against list of common issues and give you a report on issues it finds. Running this kind of a tool frequently is recommended since it finds common issues and it takes the minimum effort.

Also Android includes a tool called Lint, which checks your app code for common errors. It searches for wide variety of issues from usability to security. I strongly recommend to use lint in every project to catch easily fixable errors.

Conclusion

Writing good code is a process. It’s not particularly hard, but it takes times and effort. First you need to invest time to understand what choices improve a code base and what makes it worse. After that you need the effort to write better code and notice the things that are working well and the things that can be improved. Becoming a better coder takes time, and the only way to achieve it is to write code, lots of it and see what works and what doesn’t.