Introduction
- In software engineering, Don't Repeat Yourself (DRY) is a principle of software development.
- A principle aimed at reducing repetition of information of all kinds, especially useful in multi-tier architectures.
- The DRY principle is stated as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system".
- The principle has been formulated by Andy Hunt and Dave Thomas in their book "The Pragmatic Programmer".
- The DRY can be applied quite broadly to include "database schemas, test plans, the build system, even documentation."
- 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.
- Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync.
- DRY is known by other names as well, Once and Only Once, and Duplication is Evil (DIE).
How to Apply DRY ?
- Let's take a simple example for exploring that.
Program.cs
class Program
{
//main program
public static void Main()
{
DangerousAnimal();
PetAnimal();
TimidAnimal();
}
private static void DangerousAnimal()
{
string animal = "Dog";
string stringFormat = "{0}
is {1}, color is {2}";
Console.WriteLine(stringFormat, animal, "a dangerous animal", "brown");
}
private static void PetAnimal()
{
string animal = "Dog";
string stringFormat = "{0}
is {1}, color is {2}";
Console.WriteLine(stringFormat, animal, "a pet animal", "black");
}
private static void TimidAnimal()
{
string animal = "Dog";
string stringFormat = "{0}
is {1}, color is {2}";
Console.WriteLine(stringFormat, animal, "a timid animal", "white");
}
}
Key points of the above code
- This is obviously a very simple console app example.
- But you can see that the private methods are located in different sections on the above code snippet.
- If you want to change the animal, you’ll need to find every hard-coded instances of the animal.
- Likewise, if you want to change the stringFormat,you’ll need to update it in several different places in the above program.
How To Apply DRY for this?
Re-factoring 1 : Duplication is waste
Constant.cs
class Constant
{
public static readonly string Animal = "Dog";
public static readonly string stringFormat = "{0}
is {1}, color is {2}";
}
Key point of the above code
- We can put constant values in a separate location, such as a code file Constant.cs.
After the Re-factoring 1 :
Program.cs
{
//main program
public static void Main()
{
DangerousAnimal();
PetAnimal();
TimidAnimal();
}
private static void DangerousAnimal()
{
string animal = Constant.Animal;
string stringFormat = Constant.stringFormat;
Console.WriteLine(stringFormat, animal, "a dangerous animal", "brown");
}
private static void PetAnimal()
{
string animal = Constant.Animal;
string stringFormat = Constant.stringFormat;
Console.WriteLine(stringFormat, animal, "a pet animal", "black");
}
private static void TimidAnimal()
{
string animal = Constant.Animal;
string stringFormat = Constant.stringFormat;
Console.WriteLine(stringFormat, animal, "a timid animal", "white");
}
}
Key points of the above code
- You're in the right direction.
- If you change the constants in Constant.cs then the change will be propagated through the application.Which is good.
Re-factoring 2 :
- The values of the constants are now stored in one place.
- But what if you change the location of your constants to a different file.
- Or decide to read them from a database.
- Then again, you’ll need to revisit all the places where you use the constants in your app and change it.
- Let's try to re-factor, it again is as below.
Program.cs
class Program
{
//main
program
public static void Main()
{
DangerousAnimal();
PetAnimal();
TimidAnimal();
}
//use
class level variables
private static string animal = Constant.Animal;
private static string stringFormat = Constant.stringFormat;
private static void DangerousAnimal()
{
Console.WriteLine(stringFormat, animal, "a dangerous animal", "brown");
}
private static void PetAnimal()
{
Console.WriteLine(stringFormat, animal, "a pet animal", "black");
}
private static void TimidAnimal()
{
Console.WriteLine(stringFormat, animal, "a timid animal", "white");
}
}
Key point of the above code
- We can move those variables to the class level and use them in our app.
Re-factoring 3 : Repeated logic
- You can see that each private method performs basically the same thing.
- That is,write to the console.
- So,this is an example of duplicate logic.
- Let's try to re-factor, it again is as below.
Program.cs
class Program
{
//main
program
public static void Main()
{
DangerousAnimal();
PetAnimal();
TimidAnimal();
}
//use
class level variables
private static string animal = Constant.Animal;
private static string stringFormat = Constant.stringFormat;
/// <summary>
/// WriteToConsole method
/// </summary>
private static void WriteToConsole(string description, string color)
{
Console.WriteLine(stringFormat, animal, description, color);
}
/// <summary>
/// DangerousAnimal method
/// </summary>
private static void DangerousAnimal()
{
WriteToConsole("a dangerous animal", "brown");
}
/// <summary>
/// PetAnimal method
/// </summary>
private static void PetAnimal()
{
WriteToConsole("a pet animal", "black");
}
/// <summary>
/// TimidAnimal method
/// </summary>
private static void TimidAnimal()
{
WriteToConsole("a timid animal", "white");
}
}
Key points of the above code
- The data written to the console is very similar in each case.
- So we can move it to another private method as WriteToConsole(string description, string color).
Solution Tree
Output
That's it.You're done.
Used Dev Environment on Article's Source Code
- Visual Studio 2013 Express
- .Net Framework 4.5.1
- C#
Conclusion
- This is a very basic example of how to use a DRY with your source code.
- I have shown it under 2 categories.Which are Duplication is waste and Repeated logic.
- So always try to apply the DRY with your apps and develop awesome maintainable source code for your apps.
I hope this helps to You.Comments and feedback greatly appreciated.
If you feel it was a good article,Give me a +1.Thank You.
Really great article for DRY with basic example! Thanks so much for your effort in writing this.
ReplyDeleteAdd some real-time examples too.
Hi Sushil,
DeleteThanks, I’m glad you enjoyed it ! :)
Yep, sure. I'll add more real world examples on my future design principal articles. Thanks for the suggestion. :)
Thanks a lot sampath
ReplyDeleteHi Dedunu,
DeleteYou're warmly welcome ! :)
Good start.
ReplyDeleteHi Mukesh,
DeleteYep.It is.I'll write more about design principles in future.
Thanks for your feedback. :)
Nice article mate !
ReplyDelete