WET code and project rot

By Guy Y.

April 17, 2020

Every code base requires maintenance over time. Requirements are altered, bugs are found, features are added, and optimizations are required… It never ends.

When a change is needed, it’s much easier to handle when all the required knowledge is in a single place. This is why DRY (Do not repeat yourself) is a fundamental rule we wish to follow.

WETness (writing everything twice) should be detected and handled early on, before it leads to project rot.

Some duplications may feel unavoidable, or to be baked into the project requirements or team behavior. Automation and discipline can drastically reduce this evil.

In this post, I’ll describe some common duplication sources.

Language barrier

An example would be to represent the same model in different parts of the system.

I.e. a “User” data structure is needed at the client (written with TS/JS) and at the server (written in Java).

We can avoid such duplication by using generators. This means writing the data once in a general form, and compiling it to different languages. Google’s [protobuf](https://developers.google.com/protocol-buffers) is an example of such a code generator.

Another example would be system documentation, which is by definition a duplication.

We represent the system behavior in two forms – one is code, and the other is human language.

Even when docs are required to be separated from the codebase, it doesn’t mean they must be WET. Just like code, docs can be auto generated too. Take Angular’s compodoc for example, which generates HTML docs from the codebase JsDoc & README files.

Code inline comments

Some developers feel (or are forced to) they should add comments to the code, explaining its behavior.

I disagree.

Clean code is easy to understand. Bad code needs explaining. If a developer can’t easily follow the code and its underlying logic, it’s a strong [code smell](https://en.wikipedia.org/wiki/Code_smell).

Such WETness can be reduced by properly naming variables and methods.

Un-normalized representations

Some duplications come from data that is dependent on one another. For example:

class Circle {
  radius: number;
  diameter: number;
  circumference: number;
}

Obviously, diameter and circumference can be derived from the radius, so it can be normalized:

class Circle {
  radius: number;

  diameter() {
    return 2 * this.radius;
  }

  circumference() {
    return Math.Pi * this.diameter();
  }
}

Such normalization does come with a price. In the above example, the diameter circumference is recalculated every time we access it.

Later on, [and only if needed](https://stackify.com/premature-optimization-evil/), we may choose to violate the DRY in the name of optimization.

WET design

WET design may be hard to spot sometimes, it’s the bigger brother of the normalization issue we described above.

Consider a system that manages medical clinics:

class Clinic {
  doctors: Doctor[];
  patients: Patient[];
}

class Doctor {
  patients: Patient[];
}

class Patient {
  doctor: Doctor[];
}

Do we really need to keep track of each patient **and** each of their doctors?

A DRYer design would represent this relation in a single place. Something like this:

class DoctorPatient {
  doctor: Doctor;
  patient: Patient;
}

class Clinic {
  doctors: Doctor[]
}

class Doctor {}

class Patient {}

WET by deadline

We all face this issue at some point. We need a quick and dirty solution ASAP.

So we copy-paste the closest working one we have and then apply some minor changes and ship it away.

Such compromises are fine, but must be tracked. Leave a TODO, create a tech debt task, anything that would make sure a refactoring would find its way to your pipeline.

WET by miscommunication

The worst type of WETness are duplications created without you even knowing it. This happens when two developers create the same logic in two places without even being aware of it.

Finding those issues early (at a code review, or even better, a daily meeting) is the key.

Strong project management, collaboration and open communication would help catch such issues early on.


Make no mistake, duplication is an evil. It doubles the effort and reduces the value.

In the long run, a WET project would drown maintenance tasks, risking team frustration and business failure.

DRY discipline would minimize that risk.