Ruby Science
DRY
The DRY principle—short for “don’t repeat yourself”—comes from The Pragmatic Programmer.
This principle states:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Following this principle is one of the best ways to prevent bugs and move faster. Every duplicated piece of knowledge is a bug waiting to happen. Many development techniques are really just ways to prevent and eliminate duplication, and many smells are just ways to detect existing duplication.
When knowledge is duplicated, changing it means making the same change in several places. Leaving duplication introduces a risk that the various duplicate implementations will slowly diverge, making them harder to merge and making it more likely that a bug remains in one or more incarnations after being fixed.
Duplication leads to frustration and paranoia. Rampant duplication is a common reason that developers reach for a grand rewrite.
Duplicated Knowledge vs. Duplicated Text
It’s important to understand that this principle states that knowledge should not be repeated; it does not state that text should never be repeated.
For example, this sample does not violate the DRY principle, even though the word “save” is repeated several times:
def sign_up
@user.save
@account.save
@subscription.save
end
However, this code contains duplicated knowledge that could be extracted:
def sign_up_free
@user.save
@account.save
@trial.save
end
def sign_up_paid
@user.save
@account.save
@subscription.save
end
Application
The following smells may point toward duplicated code and can be avoided by following the DRY principle:
- Shotgun surgery caused by changing the same knowledge in several places.
- Long parameter lists caused by not encapsulating related properties.
- Feature envy caused by leaking internal knowledge of a class that can be encapsulated and reused.
Making behavior easy to reuse is essential to avoiding duplication. Developers won’t be tempted to copy and paste something that’s easy to reuse through a small, easy to understand class or method. You can use these solutions to make knowledge easier to reuse:
- Extract classes to encapsulate knowledge, allowing it to be reused.
- Extract methods to reuse behavior within a class.
- Extract partials to remove duplication in views.
- Extract validators to encapsulate validations.
- Replace conditionals with null objects to encapsulate behavior related to nothingness.
- Replace conditionals with polymorphism to make it easy to reuse behavioral branches.
- Replace mixins with composition to make it easy to combine components in new ways.
- Use convention over configuration to infer knowledge, making it impossible to duplicate.
Applying these techniques before duplication occurs will make it less likely that duplication will occur. To effectively prevent duplication, make knowledge easier to reuse by keeping classes small and focused.
Related principles include the Law of Demeter and the single responsibility principle.
Ruby Science
The canonical reference for writing fantastic Rails applications from authors who have created hundreds.