dry

DRY Principle: Avoid Duplicating Knowledge

  • 4 min

The DRY principle (Don’t Repeat Yourself) states that every piece of knowledge in a system should have a single, unambiguous representation within the code.

Put simply: if a rule changes, we should only need to modify it in one place. If we have the same validation, calculation, or query repeated in five places, the day a condition changes, we’ll have to remember all five. And you know how that usually ends.

DRY does not mean “never repeat two similar lines”. It means do not duplicate knowledge. This difference seems small, but it avoids many pointless abstractions.

The Problem of Repeating Knowledge

Suppose we have a simple business rule: orders over 100 euros get free shipping.

If this rule is repeated throughout the application, we have a problem:

if (pedido.Total > 100)
{
    costeEnvio = 0;
}
Copied!

And then somewhere else:

bool tieneEnvioGratis = carrito.Total > 100;
Copied!

And further down the line:

return totalCompra > 100 ? "Envio gratis" : "Envio normal";
Copied!

The code seems innocent, but the rule is duplicated. If marketing decides tomorrow that free shipping starts at 120 euros, we have to find all the copies.

And if we miss one, the application starts behaving differently depending on the screen. Wonderful.

Applying DRY

The solution is to express that rule once, with a name that explains its intent.

public class PoliticaEnvio
{
    private const decimal ImporteMinimoEnvioGratis = 100m;

    public bool TieneEnvioGratis(decimal total)
    {
        return total >= ImporteMinimoEnvioGratis;
    }
}
Copied!

Now the rest of the code doesn’t need to know the magic number. It just asks:

if (politicaEnvio.TieneEnvioGratis(pedido.Total))
{
    costeEnvio = 0;
}
Copied!

This is much better because the rule lives in a single place. Changing it is easy, testing it is easy, and reading the code is also easier.

DRY is Not About Abstracting Everything

This is the important part. DRY does not mean that every time you see two similar lines you must create a class, an interface, three generics, and a Factory pattern because you got carried away.

Two pieces of code can look the same and yet represent different concepts.

For example:

decimal descuentoCliente = total * 0.10m;
decimal ivaProducto = total * 0.21m;
Copied!

Both lines multiply by a percentage. But one talks about discounts and the other about taxes. If we lump them into a common abstraction too early, we might have created an artificial dependency between two things that should evolve separately.

Accidental duplication should be corrected. Accidental similarity should be tolerated.

If you’re not sure that two pieces of code change for the same reason, wait a bit before abstracting.

DRY and Design Patterns

Design patterns often help apply DRY because they allow us to isolate a variation in a specific part of the system.

For example:

  • With Strategy, we avoid repeating similar algorithms scattered across switch statements.
  • With Factory, we centralize creation logic.
  • With Template Method, we keep the skeleton of an algorithm common and move the variable steps.
  • With Repository, we avoid repeating queries and persistence details throughout the application.

The idea is not “use patterns just because.” The idea is that when we detect a repeated responsibility, we place it where it makes sense.

When It’s Worth It

DRY is especially worthwhile when the repetition affects:

  • Business rules, because they change and often have consequences.
  • Validations, because if they diverge they generate strange errors.
  • Queries or data access, because they duplicate technical details.
  • Configuration, because scattered magic values are a ticking time bomb.
  • Algorithms, because fixing a bug in one copy and forgetting another is very common.

On the other hand, it’s okay to repeat a bit of code if it makes two modules clearer and more independent.

A good clue: if changing a rule makes you use the IDE’s search function with fear, there is probably knowledge duplication.

DRY is one of those simple principles that seem obvious, until an application grows and we discover that the same rule is hidden in twenty places.

Applying it well consists of eliminating real duplication, not fabricating abstractions as a sport. When an idea belongs in a single place, the code becomes easier to maintain, easier to test, and much less prone to surprises.