In this post, you will see two examples to show the need for DRY principal and ways to fix the problems.
Introduction
DRY is one of the most fundamental software development 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 four different places (or programs).
You can simply copy this single line (Integer.parseInt()
) to four 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 four files, you have to fix it in all places.
This is what the DRY principle says, Don't repeat yourself!!! If you would have created a utility method to convert a String
to Integer
and called the method from all those four 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)
{
}
return i;
}
}
Example 2
Let's look at the below code. Here, the hardcoded URL "https://www.thebackendpro.com/" is used in all four methods. Now, if you want to change this hard coded URL to "https://www.google.com/", you have to do the same in all four methods, which is cumbersome as well as error prone.
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 to change the url in all four places. If you want to change the url to a different one, you have to make changes in all four 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);
}
}