DRY Don't Repeat Yourself In Terms of Code
The DRY principle, "Don't Repeat Yourself," guides against duplicating code to make it more maintainable, less error-prone, and easier to update.
Instead of duplicating, extract abstractions.
DRY=Do it ONCE.
Though shall not copy paste code.
Benefits of DRY (Don't Repeat Yourself):
-
Simplified Maintenance: Changes need to be made in just one place, reducing the effort and risk involved in code maintenance.
-
Reduced Bug Risk: With single-source code, the likelihood of bugs spreading through duplication is minimized. Bugs fixed in one place are fixed system-wide.
-
Enhanced Readability: DRY code tends to be more organized and modular, making it easier to understand, which is especially beneficial for new team members.
-
Improved Scalability: Less code means lighter, more agile applications. DRY practices contribute to a codebase that scales more gracefully.
-
Consistency: A single source of truth for each piece of logic ensures consistent behavior throughout the application.
-
Optimization Opportunities: It's easier to optimize a codebase where each piece of logic is maintained in one place. Performance improvements benefit the entire application.
-
Easier Testing: DRY principles often lead to a more testable code structure since you can test single units of logic thoroughly and be confident they work correctly wherever used.
Incorporating DRY principles typically leads to a codebase that's more maintainable, scalable, and robust, providing a solid foundation for growth and development. Conversely, WET code tends to introduce risks and inefficiencies that can significantly hinder a project's long-term viability.
Not all code duplication is knowledge duplication
DRY is not to be used blindly but rather USED to remove knoweldge duplication rather than pure code duplicadtion
As part of your online wine ordering application you’re capturing and validating your user’s age, along with the quantity they’re ordering. According to the site owner, they should both be numbers, and both greater than zero. So you code up the validations:
def validate_age(value):
validate_type(value, :integer)
validate_min_integer(value, 0)
def validate_quantity(value):
validate_type(value, :integer)
validate_min_integer(value, 0)
During code review, the resident know-it-all bounces this code, claiming it’s a DRY violation: both function bodies are the same.
They are wrong. The code is the same, but the knowledge they represent is different. The two functions validate two separate things that just happen to have the same rules. That’s a coincidence, not a duplication. - Pragmatic Programmer (Book)
Perils of WET code
Perils of WET code
WET (Write Everything Twice) Perils:
-
Maintenance Nightmare: With duplicated code, any change needs to be replicated across all instances. This makes maintenance cumbersome and error-prone.
-
Bug Propagation: If a bug exists in a duplicated code segment, it’s likely present everywhere the code is replicated. This can lead to widespread system vulnerabilities.
-
Increased Complexity: WET code often leads to bloated, complex systems that are hard to understand and navigate, making it challenging for new developers to onboard.
-
Scalability Issues: As the system grows, so does the duplicated code, leading to heavier, less manageable, and slower applications.
-
Inconsistency Risks: It’s easy to update one instance of the code and miss others, leading to inconsistent behavior across the application.
-
Poor Optimization: Duplicate code makes it harder to implement optimizations. Changes meant to improve performance must be applied in multiple places, increasing the risk of missing some.
Quotes
When the DRY principle is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements. - wiki
Resources
Balancing out with real world:
While DRY is important. It's also important to not be dogmatic. And evaluate tradeoffs of real world.
A little copying is better than a little dependency
A little copying is better than a little dependency. - go-proverbs/video-ref
Take note of Rule of 3
DRY in its purist form can be a bit idealistic.
Hence, rule of 3 comes to balance it out.
The Rule of Three is a pragmatic approach to the DRY Don't Repeat Yourself In Terms of Code. While DRY emphasizes reducing duplication to maintain cleaner and more maintainable code, the Rule of Three acknowledges that duplication is sometimes unavoidable or even beneficial in the short term.
Key Points
-
Duplication Tolerance:
- First Time: When you write a piece of code for the first time, it's natural and necessary. No duplication exists at this stage.
- Second Time: When you need to duplicate code a second time, it's at times acceptable. This allows you to explore different contexts and understand how the code is being reused.
- Third Time: When you find yourself duplicating code for the third time, it's a signal that the code should be refactored. By the third instance, it's clear that the functionality is common enough to warrant abstraction.
-
Advantages:
- Clarity: Initially, allowing some duplication can make the code clearer and simpler to understand, especially when the exact needs of abstraction are not yet evident.
- Flexibility: By the time you need to abstract the duplicated code, you have better insights into how it should be structured to serve multiple use cases effectively.
- Avoiding Premature Abstraction: Prematurely abstracting code can lead to over-engineering. The Rule of Three helps in avoiding unnecessary complexity.
-
Application:
- Monitor for duplication during code reviews.
- Use the third occurrence as a trigger to refactor and abstract the common code.
- Ensure that the abstraction is well-named and self-documenting to maintain code readability.
Example
// First time: Code to send an email
public void sendEmail(String recipient, String subject, String body) {
// logic to send email
}
// Second time: Code to send an SMS
public void sendSms(String phoneNumber, String message) {
// logic to send SMS
}
// Third time: Similar logic appears again for sending notifications
public void sendNotification(String type, String recipient, String message) {
if (type.equals("email")) {
sendEmail(recipient, "Notification", message);
} else if (type.equals("sms")) {
sendSms(recipient, message);
}
}
// Refactor the common sending logic
public void send(String type, String recipient, String subject, String message) {
if (type.equals("email")) {
// logic to send email
} else if (type.equals("sms")) {
// logic to send SMS
}
}
By following the Rule of Three, you ensure that your code remains maintainable, readable, and efficient. This approach strikes a balance between avoiding premature optimization and adhering to the DRY principle.
Children
- DRO-dont-repeat-others-Integrate
- Not All Code Duplication Is Knowledge Duplication
- Rule of Three
- vs-WET-write-everything-twice-perils
Backlinks