Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save svevang/8721d1fdc9bd7059b3d1f8de3dcf53a8 to your computer and use it in GitHub Desktop.
Save svevang/8721d1fdc9bd7059b3d1f8de3dcf53a8 to your computer and use it in GitHub Desktop.

Code Maintainability

Code maintainability encapsulates the idea of how easy it is to alter existing features or add new features. Changes to software originate in various places: User requirements tend to change with time, new features are requested and existing features may be need to be modified. In addition to the needs of the user or business, associated platforms and tooling can also change, as anyone who has worked through XCode upgrades can attest.

We need to ensure that our software products can adapt and respond over time. From a planning and user-satisfaction perspective, we obviously want to maintain a constant velocity of releases. Velocity is a dual measure of feature complexity and code complexity. Code maintainability in this sense means that we can move through feature space and we'll not be slowed down by intrinsic properties of the code.

The code itself can slow feature development down for a lot of reasons. Technical debt is one reason: previous features made short term productivity gains by depositing unwieldy/inflexible structures in the codebase. Another reason is that new features can cross-cut assumptions made much earlier in the development process, meaning that instead of a single addition to the code, we now need to refactor across a set of internal APIs, restructuring our parameters and associated semantics.

So code maintainability is important, and like software itself, it's not a clearly posed problem. There are a best practices situated at the level of framework or platform, but generally some practices that I follow and encourage others to follow:

Keep system components loosely coupled.

Code that is loosely coupled and has clear interfaces is easier to refactor in the case of a cross-cutting concern.

Break up large blocks of complicated code

Make sure your functions are reasonably sized and have a specific focus. Unit testing can help here.

Strive for idiomatic code.

Don't do things that are surprising. This is important especially when working on teams, we want to be able to pick up where someone leaves off. Often this means scanning the code for intent.

Dev Environment

I use conventional Unix/GNU OSS development tools centered on Vim.

My main development machine a MacBook Pro and I'm in Bash and Vim most of the time. Syntastic, NERDTree, AckGrep (Ag), and various other Vim plugins make life a lot easier. My Vim setup has worked out really well for languages like ruby, python and elixir. When I'm working on iOS, it's XCode. If I were working with typed languages, I'd jump to a proper IDE (I've heard good things about Visual Studio).

I use tmux all the time to manage my development sessions. Tmux has good support for tabs, so I'll have all my running programs and vim situated in a group of tabs. Tmate (a tmux proxying service) and Hangouts for remote pairing is nice. No need to squint at a pixelated terminal interface.

I'm a big fan of rbenv-like abstractions around tooling. For ruby it's rbenv and Gemfiles. For python it's pip and pyenv/virtualenv for managing and locking package versions.

For tracking development, I've variously used Github issues, Trello, Pivotal tracking . Anything works, but I tend to stick to the Pivotal style of estimating and breaking up tasks into reasonable chunks. Daily standups help free anything that's blocking progress. Retrospectives reflections on what went right and what when wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment