Skip to content

Instantly share code, notes, and snippets.

@johnmcfarlane
Last active October 20, 2025 08:36
Show Gist options
  • Select an option

  • Save johnmcfarlane/fb365c6b81a23195897d7cf461d336ce to your computer and use it in GitHub Desktop.

Select an option

Save johnmcfarlane/fb365c6b81a23195897d7cf461d336ce to your computer and use it in GitHub Desktop.
Essential

Essential Principles

Commonly occuring good advice aimed at improving maintainability.

Brevity

  • Avoid duplication, tautology, repetition, duplication, and saying the same thing over and over in different ways.
  • Everything (words, statements, comments) should have a clear purpose.

Resources

Simplicity

  • Avoid complexity.
  • Encourage simplicity.

Resources

Modularity

Examples

Modularity extends far beyond C++ modules or translation units, and includes the organisation, contents within and relationships between:

  • Functions
  • Objects
  • Source files
  • Packages
  • Documents
  • Standards and Conventions
  • Projects
  • Teams

Build Systems vs Toolchain Configuration

Many well-meaning projects store toolchain configuration in their build system description. Here's an example of a C++ project combining the concerns of configuring a specific compiler, with describing build targets. This is very common because CMake makes it easy to do. In reality, a CMakeLists.txt file should never contain a compiler flag because this couples the description of what targets to make (a build system concern) with what flags to pass when building (a toolchain concern). The result is a brittle configuration which breaks immediately when a novel toolchain is used.

Consistency

Within any organisational unit cohesion is increased where lower-impact decisions (formatting, naming, and paradigm conventions) are applied consistently throughout.

Limitations

Individual units may be constituent parts of a larger unit, e.g. multiple package dependencies in a project. The sub-units should be free to make and apply contrary decisions, otherwise coupling ensues.

Cyclic Dependencies

  • Avoid cycles in your graphs.

Examples

  • Recursion
  • CI pipelines which are triggered by pushes, and also cause pushes (see GitLab guidelines).

Fail Well

If something disappointing happens:

  • fail
  • don't try to muddle on
  • don't try to be 'helpful' to get around the problem with the addition of complexity.

Examples

  • When a std::map::operator[] lookup failed to find an element matching the given key, it creates one instead. This leads to a cascade of additional complexity in the design, and makes the API less reasonable in the case that the looking is successful.

Patterns are Paramount

Examples

  • Don't Repeat Yourself / Avoid Tautology, i.e. describe the pattern; don't be the pattern

  • When tautology exists in the domain, model it, e.g.:

    • if a model uses "ATM Machine", don't be afraid to write a variable, automatic_teller_machine_machine. This isn't tautology in the nameing, merely a reflection of unavoidable tautology in the system.
    • if a library reuses names, e.g. fmt::format, string::string, or ranges::range, in a tutological name, don't try to avoid this tautology when you model around it.
    • If Sarah of Sarah's Sandwiches has a nametag, it's path might be "/Sarah's Sahdwiches/Sarah/Sarah's nametag.svg". Given the nametag files might be copied to a common location, this is either not tautological, or perferable to a DRYer filename.

Refine Your Solutions

Most poor solutions I see appear to be the authors first attempt at a solution.

Resources

More Things

  • Command / Query - goes under UNIX way: each thing does only one thing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment