Saturday, April 12, 2014

What is DRY ?

Introduction

  • This Article explores design principle DRY (Don’t Repeat Yourself)

What is DRY


What is DRY ?

  • 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

class Program
    {

        //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

What is DRY

Output

What is DRY


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.


7 comments:

  1. Really great article for DRY with basic example! Thanks so much for your effort in writing this.
    Add some real-time examples too.

    ReplyDelete
    Replies
    1. Hi Sushil,

      Thanks, 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. :)

      Delete
  2. Thanks a lot sampath

    ReplyDelete
  3. Replies
    1. Hi Mukesh,

      Yep.It is.I'll write more about design principles in future.
      Thanks for your feedback. :)

      Delete

Thanks for your Feedback.