DRY (Don't Repeat Yourself)
DRY is one of the most fundamental software design principles. Which tells us to not repeat the same piece of code more than once.
Repetition (or Redundancy) is quite a common problem in software development, as it hampers the maintainability of the software.
Example 1
Let's think you want to convert a String to an Integer and you can just simply use Integer.parseInt(). Now, suppose you need this functionality in 4 different places (or programs).
You can simply copy this single line (Integer.parseInt()) to 4 places(or programs) as below.
package dry;
public class DryTest1 {
public void parseToInt(String s) {
System.out.println(Integer.parseInt(s));
}
public void parseToIntAdd10(String s) {
int i = Integer.parseInt(s);
System.out.println(i+10);
}
public void parseToIntAdd20(String s) {
int i = Integer.parseInt(s);
System.out.println(i+20);
}
public void parseToIntAdd30(String s) {
int i = Integer.parseInt(s);
System.out.println(i+30);
}
}
Now the real problem is when you try to parse a String that is not an Integer, Integer.parseInt() throws a runtime exception. So, now you want to fix this problem. But since you have copied this piece of code to 4 files, you have to fix it in all places.
This is what the DRY principle says, Don't repeat yourself!!!. If you had created a utility method to convert a String to Integer and called the method from all those 4 places, it would be simpler to fix the issue in one place. This is how we can maintain the software, easily.
How to fix the above problem?
Create a utility method either in the same class or some other utility class. If you want to use the same method in multiple classes, it's advised to create it in a utility class.
package dry;
public class DryTest2 {
public void parseToInt(String s) {
System.out.println(parseToInteger(s));
}
public void parseToIntAdd10(String s) {
int i = parseToInteger(s);
System.out.println(i+10);
}
public void parseToIntAdd20(String s) {
int i = parseToInteger(s);
System.out.println(i+20);
}
public void parseToIntAdd30(String s) {
int i = parseToInteger(s);
System.out.println(i+30);
}
public int parseToInteger(String s) {
int i = 0;
try {
i = Integer.parseInt(s);
} catch(RuntimeException e) {
// suppressing the exception
}
return i;
}
}
Example 2
Let's look at the below code. Here the hard-coded URL "https://www.thebackendpro.com/" is used in all 4 methods. Now if you want to change this hard-coded URL to "https://www.google.com/", you have to do the same in all 4 methods, which is cumbersome and as well as error-prone.
What if you forgot to change in one place? Your QA identifies and fix needs to be delivered.
If you follow the DRY principle, all these issues won't appear.
package dry;
public class DryTest2 {
public void m1() {
System.out.println("https://www.thebackendpro.com/");
}
public void m2() {
System.out.println("https://www.thebackendpro.com/");
}
public void m3() {
System.out.println("https://www.thebackendpro.com/");
}
public void m4() {
System.out.println("https://www.thebackendpro.com/");
}
}
Let's think you are ok with changing the URL in all 4 places. If you want to change the URL to a different one, you have to make changes in all 4 places again. Every time the URL changes, you have to update all the places. What if you forgot to change in one place? Your QA identifies and fix needs to be delivered.
If you follow the DRY principle, all these issues won't appear.
How to fix the above problem?
Instead of hardcoding the url in all places, Just define a constant, as below. Whenever you want to change the URL, you can simply change the constant.
package dry;
public class DryTest {
private static final String url = "https://www.thebackendpro.com/";
public void m1() {
System.out.println(url);
}
public void m2() {
System.out.println(url);
}
public void m3() {
System.out.println(url);
}
public void m4() {
System.out.println(url);
}
}
Tips for adapting DRY
- Avoid Hardcoding Strings - If you want to use a String Constant, don't hardcode it where ever it is required. Instead, create a constant and use that where ever necessary.
- Reusability - Split the code & logic into smaller reusable methods & call these methods where ever you want.
- Don't write lengthy methods, always segregate the method into smaller methods and re-use.
Benefits of DRY
- Improves code readability.
- Makes code maintenance easier thereby reducing the chances of bugs.