Skip to content

Building Maintainable Software

Building Maintainable Software

Building Maintainable Software, C# Edition: Ten Guidelines for Future-Proof Code by Joost Visser and his colleagues from the Software Improvement Group (SIG). The book is based on the analysis of hundreds of real-world software systems and aims to provide practical, measurable guidelines for improving software maintainability.


The book is essentially a maintainability handbook for developers and technical leaders.

Rather than discussing design patterns, DDD, CQRS, or advanced architecture styles, it focuses on foundational practices that make code easier to:

  • Understand
  • Change
  • Extend
  • Debug
  • Test
  • Transfer between team members

The authors define maintainability as the ability to modify software efficiently and safely over time.

Several chapters focus on individual methods and classes.

Examples:

Write Short Units

Methods should be small enough that a developer can understand them quickly.

Instead of:

public void ProcessOrder(...)
{
// 200 lines
}

Use:

public void ProcessOrder(...)
{
ValidateOrder();
CalculatePrice();
ReserveInventory();
CreateInvoice();
}

The goal is to reduce cognitive load.

Write Simple Units

The book strongly discourages excessive branching and complex decision trees.

Bad:

if (...)
{
if (...)
{
if (...)
{
...
}
}
}

Complexity directly impacts maintainability.

The authors encourage measuring complexity and keeping it under control.

Write Code Once

Avoid duplication.

Copy-paste programming creates hidden maintenance costs.

When a bug is fixed in one location but not the others, defects emerge.

The next set of guidelines focuses on creating coherent modules.

Keep Unit Interfaces Small

Classes with many parameters and many public methods tend to become difficult to understand and use.

Instead of:

CreateUser(
string firstName,
string lastName,
string address,
string city,
string zip,
string country);

Use:

CreateUser(UserInfo user);

Smaller interfaces are easier to evolve.

Separate Concerns

A class should have a focused responsibility.

Bad example:

OrderService

Handles:

  • Validation
  • Database access
  • Reporting
  • Email sending
  • Logging

Better:

OrderValidator
OrderRepository
EmailNotifier
ReportGenerator

You can clearly see the influence of SOLID principles here.

The book then zooms out from classes to systems.

Loosely Coupled Components

Changes in one component should not create cascading effects elsewhere.

For example:

UI
|
API
|
Domain
|
Infrastructure

is generally easier to maintain than a mesh of dependencies where every component depends on every other component.

Balanced Components

The authors observed that healthy systems typically avoid:

One giant component Hundreds of tiny fragmented components

Both extremes create maintenance problems.

A system should have reasonably balanced subsystems.

Keep the Codebase Small

One of the most overlooked ideas in the book:

The best code is often the code you never write.

Every line of code carries future maintenance cost.

The authors encourage:

  • Removing dead code
  • Removing obsolete features
  • Reusing frameworks where appropriate
  • Simplifying solutions

The final guidelines focus on sustainable engineering practices.

Automate Tests

Manual testing does not scale.

Automated tests serve as:

  • Change detectors
  • Documentation
  • Safety nets

A maintainable codebase is difficult to achieve without them.

Write Clean Code

The book aligns with many ideas from Robert C. Martin’s Clean Code:

  • Meaningful names
  • Consistent conventions
  • Removal of code smells
  • Readable code

The difference is that SIG attempts to connect these ideas to measurable maintainability outcomes rather than treating them as stylistic preferences.


The central message is:

Software maintainability is not a matter of opinion. It can be measured, improved, and managed through a small set of concrete coding and architectural practices.

The authors argue that most software projects become expensive and risky not because of incorrect functionality, but because the codebase gradually becomes harder to understand, modify, and extend. Maintainability should therefore be treated as a first-class quality attribute, just like security, performance, and reliability.

The book distills maintainability into ten practical guidelines:

  1. Write short units of code
  2. Write simple units of code
  3. Write code once
  4. Keep unit interfaces small
  5. Separate concerns in modules
  6. Couple architecture components loosely
  7. Keep architecture components balanced
  8. Keep your codebase small
  9. Automate tests
  10. Write clean code

If you remember only one thing from the book, it is this:

Future development speed depends more on the health of the existing codebase than on the talent of individual developers.


Many developers focus on writing code that works today.

Businesses care about:

How much will it cost to modify this system in three years?

Maintainable code reduces long-term ownership costs.

A common misconception:

Messy code = faster delivery

Reality:

Messy code = faster today
Messy code = slower every future release

As technical debt accumulates:

Features take longer Bugs increase Testing becomes harder Refactoring becomes risky

One of the book’s strengths is that it is not primarily opinion-driven.

The recommendations were derived from large-scale analysis of real software systems by SIG consultants.

This makes the book particularly valuable for technical leads and architects who need objective reasoning when discussing code quality.

Many books explain how to write cleaner code.

This book explains why executives should care:

  • Reduced maintenance costs
  • Faster development
  • Lower defect rates
  • Easier onboarding
  • Longer software lifespan

In summary:

The book teaches that maintainable systems emerge from controlling complexity at every level: methods, classes, modules, architecture, and development process. The ten guidelines provide a practical framework for keeping software adaptable, understandable, and cost-effective over its entire lifetime.

For a C# developer, the most valuable chapters are usually Write Simple Units, Separate Concerns, Couple Components Loosely, and Automate Tests, because those four principles tend to produce the largest long-term impact on enterprise .NET codebases.