Don’t Repeat Yourself

“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

(Source: http://en.wikipedia.org/wiki/Don’t_repeat_yourself)

“Each significant piece of functionality in a program should be implemented in just one place in the source code. Where similar functions are carried out by distinct pieces of code, it is generally beneficial to combine them into one by abstracting out the varying parts.”

(Source: http://en.wikipedia.org/wiki/Abstraction_principle_(programming))

This principle applies to algorithms, architecture, tests, data, server configuration, model, view, controller, user interface, CRUD, etc.

Data Example – If a particular class of object contains a set of fields (e.g. name, height, age, id) these fields will probably be represented in a number of different places (Object Relational Mapping, database schema, unit test sample data and assertions, documentation, JavaScript form validation, controller input scrubbing, model/controller output, CRUD view HTML, entity page view HTML, etc). In an ideal Don’t Repeat Yourself system, adding a new field would only have to be done in one single place. All the other representations should be programmatically generated from the central canonical authoritative representation. An example would be the YAML files that define schemas in Doctrine.

Algorithm Example – If several classes/functions all use nearly identical logic, that logic should be refactored into a more abstract class with concrete instances that only provide the bits of data that are unique to each variation on the logic.

Documentation Example – Don’t write documentation that says the same thing as your code. Wherever possible generate documentation directly from self-descriptive functional executable code. If your documentation is generated from a functional source, it is guaranteed to stay in sync with the code. However, if you write static text documentation that describes the same thing as your code, you may change the code and forget to change the documentation; this renders the documentation a liability rather than an asset.

Avoid premature abstraction. The first time you say something, you don’t need to say it abstractly. You should wait to abstract it until you have to say it a second time. Not repeating yourself will require refactoring, or it may require the creation of a new code-generation tool. Do not for a second imagine that skipping this refactoring or deferring the creation of the tool will save you time. Instead, it may save you a few hours today, but it will cost you hours of time and a proliferation of bugs every single time you have to perform a similar repetition.