“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”
“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.”
This principle applies to algorithms, architecture, tests, data, server configuration, model, view, controller, user interface, CRUD, etc.
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.