Don't Repeat Yourself

This post was written by Salaikumar.

Principles. Software Engineering principles. Anyone remember the syllabus/topics the paper covered in our Engineering? I wish I could. Less did I know that I would need those principles as I grew in my career.

Anybody can write code. But in human-understandable form?

That's the realization point. Coding is an art, Indeed. A maintainable codebase is something companies are thriving to achieve.

Philosophies apart. We are gonna try learning one essential principle. "Don’t Repeat Yourself (DRY)."

So, What’s this Principle is all about?

One of the reasons why I didn't learn Software Engineering principles in college is the overwhelming theoretical explanations without a practical approach to back it up.

Let's jump straight into examples and learn from it.

Use Methods/Functions for DRYness

Let's take the below classes

package net.geekyminds.blog.dry;

/**
 * Subroutine Demo
 * The class represents the use of methods(since java is object orientation)
 * Created by salaikumar on 11/5/17.
 */
public class MethodsAndDRY {

    /**
     * Main method
     * @param args
     */
    public static void main(String[] args) {
        // A program that prints a dotted line after each heading.
        System.out.println("****************  - DRY Principle - ***************");
        System.out.println("---------------------------------------------------");
        System.out.println("DRY is a awesome principle. But I just don't care to apply it my programs.");


        System.out.println("****************  - SOLID Principle - ***************");
        System.out.println("---------------------------------------------------");
        System.out.println("Only stupids out there keep on reading principles. But my code still works!!");


        System.out.println("**************** - YAGNI Principle - **********************");
        System.out.println("---------------------------------------------------");
        System.out.println("Anyhow, I completed the feature for client. What else you would expect? ");

    }
}

How about another class that does the same functionality?

package net.geekyminds.blog.dry;

/**
 * Created by salaikumar on 11/5/17.
 */
public class MethodsForDRY {


    public static void addSectionsWithDescriptons(String title, String tagLineOfLazyProgrammer){
        System.out.println("****************  - "+ title +" - ***************");
        System.out.println("---------------------------------------------------");
        System.out.println(tagLineOfLazyProgrammer);
    }
    /**
     * Main method
     * @param args
     */
    public static void main(String[] args) {
        // A program that prints a dotted line after each heading.
        addSectionsWithDescriptons("DRY Principle","DRY is a awesome principle. But I just don't care to apply it my programs.");
        addSectionsWithDescriptons("SOLID Principle","Only stupids out there keep on reading principles. But my code still works!!");
        addSectionsWithDescriptons("YAGNI Principle","Anyhow, I completed the feature for client. What else you would expect? ");

    }
}

Which one do you prefer/consider as good program?

I would go with the second one. That's the simple essence of DRY. From my understanding, all it says is don't enjoy typing the same piece of code/functionality again and again. Just see how you can write it once and apply it whenever required. My understanding would say DRY gave the necessity for Functions/Subroutines.

Utility classes

Ever heard of java.util package? Yes, my suggestion is to take it as a primary example when you start writing modules. Move the frequently used functionalities to Util classes and keep things organized within the package.

My humble suggestion is to go through the package. Spend time using the package, write classes using it and learn how it helps you to be DRY.

Sometimes Overload yourself to be DRY

package net.geekyminds.blog.dry;

/**
 * Two Methods that has almost does the same functionality , Seems repetitive isn't?
 * Created by salaikumar on 11/5/17.
 */
public class MethodOverloadingForDRY {

    /**
     * Get's the title and tagline and prints it nicely
     * @param title
     * @param tagLineOfLazyProgrammer
     */
    public static void printTitleAndTag(String title, String tagLineOfLazyProgrammer){
        System.out.println("****************  - "+ title +" - ***************");
        System.out.println("---------------------------------------------------");
        System.out.println(tagLineOfLazyProgrammer);
    }

    /**
     * Get's title and tagline and prints it without an underline
     * @param title
     * @param tagLineOfLazyProgrammer
     */
    public static void printTitleAndTagWithoutUnderLine(String title, String tagLineOfLazyProgrammer){
        System.out.println("****************  - "+ title +" - ***************");
        System.out.println(tagLineOfLazyProgrammer);
    }


    /**
     * You give the user the same functionality as above, but without repeating yourself, right? 
     *  -- You provide more flexibility to user to chose
     *  -- You don't have same lines of code in two methods
     *  -- You had made one method call another without it repeating the same functionality
     */

    /**
     * Pretty prints the given header and tagline
     * @param title
     * @param tagline
     */
    // How about not too many params when you just wanna pretty print?
    public static void prettyPrintTagAndHeader(String title, String tagline){
        // Call the same method with just passing a value on it's own?
        prettyPrintTagAndHeader(title, tagline, false);
    }

    /**
     * Pretty prints the given header and tagline with/without underline as per the user choice
     * @param title
     * @param tagline
     * @param withUnderline
     */
    // I want to me more specific. I decide if I need a underline or not in my pretty print
    public static void prettyPrintTagAndHeader(String title, String tagline, boolean withUnderline){
        System.out.println("****************  - "+ title +" - ***************");
        if (withUnderline)
            System.out.println("---------------------------------------------------");
        System.out.println(tagline);
    }

}

The above is a simple example of using Overloading to avoid two methods doing the same work, but both implementing it again. I don't need to maintain both the methods if at all I would need to bring a change later on.

Where to go from here?

It's a blog to give you the essence of DRY principle. There are multiple ways a language enforces DRY and multiple patterns that help you follow it. That's topic for another night.

DRY plays an essential role in creating a maintainable code base. As a project grows, you don't want programmers reinventing a wheel. Keeping Utility/Helper classes with clean APIs saves a lot of time.

Hope it helps. Let's do another learning together soon.