Programming Principles and Best Practices DRY AND KISS

I generally follow these patterns with all my developments. They start with “the big 7” – Object Oriented Design Principles, SOLID, GRASP, DRY, KISS, Don’t Tell Us, Design Patterns. They play important role in several phases: code writing, code review and debugging. If you follow them you will save time and headache - for you and your colleagues. After several months of practicing and learning them you can be good enough and start seeing results and benefits. I wanted to share them with some practical examples.

DRY(Don't Repeat Yourself)

The first principle of software development is Don't Repeat Yourself (DRY) . It's very important one and easy to learn. Sometimes can be difficult to verify is a particular piece of code really a violation of the rule.

Example:

Lets say you are working on a application (technologies, frameworks, languages doesn't really matter in this case). There is a class or model/domain object named Student and a class/controller called StudentClass(if you use MVC model/domain, controller, view). In the StudentClass there are several methods show, edit, find etc. All of them following the similar pattern:

  • Get the ID of the object from the parameters.
  • Find the student.
  • Doing some action on the Student.

If you find some of this steps repeating in more than one method than you can do a separate method for them.

Encapsulating first steps into a new method called getStudent. A code example in groovy:

    Student getStudent(def id) {
        def student = Student.get(id)
        if(student) {
            c.call student
        }else{
            //throw exception or redirect
        }
        return student
    }
    //dry example
    private def save(def id) {
       Student student = getStudent(id)
       student.delete()
    }
    private def delete(def id) {
       Student student = getStudent(id)
       student.save()
    }
    
    //not a dry example
    private def save(def id) {
        def student = Student.get(id)
        if(student) {
            student.save()
        } else{
            //throw exception or redirect
        }
    }
    private def delete(def id) {
        def student = Student.get(id)
        if(student) {
            student.delete()
        } else{
            //throw exception or redirect
        }
    }
//other violations 
    def var1 = 0 //violation
    def var2 = 0 //violation
    def var3, var4 = 0 // ok

KISS (Keep it short and simple)

Keep an simple implementation may sounds very simple but it's not. Tempting to add new functionalities, using trends or just showing off how good are you - can keep you away from this principle. In general is to stick to minimalism and the basic features. Don't do fancy stuff, don't write a code that you will need days to decode after a month time.
These are two methods doing one and the same thing. Here is not easy to say which one is better:

def getMonth(int month)
{
    switch (month)
    {
        case 1: return "January";
        case 2: return "February";
        ***
        case 12: return "December";
        default: println("months are only 12");
    }
}
 
def getMonth1(int month)
{
    if (month < 1) 
        println ("months are only 12");
        
    if (month > 12)
        println ("months are only 12");
 
    String[] months = ["January", "February",***, "December"];
 
    return months[month-1];
}

println getMonth1(2)
println getMonth(2)

but what about this post:

Reverse Engineering One Line of JavaScript

As you can see the two examples in the post are doing one and the same thing. But with great difference in the readability. Unless for me

Related Article