How I reduced Debugging Time

Sep 23, 2017

I remember 4 years ago, programming looked something like this. Write code, big chunks of code, run to see if they work correctly then debug it to find the source of the problem.
I was having a conversation with a friend, and a subject popped up. When was the last time you used the debugger ? At first I thought the answer will be simple. But I didn't recall that. That doesn't mean I don't debug my code. I do , but I just use some simple console outputs.
I was quite intrigued. The projects I am working on are more complex compared with those I worked on before . But still I didn't need to use the debugger.
Before I memorized every debugging shortcut. How to step in, out.
The question that I asked myself at that moment was : what changed?

Planning

I was told again and again to take the time to plan before doing anything. But my ego was as tall as the empire state building. I would fire up the IDE/Editor and start writing code, to find myself quickly spending hours debugging.

So before jumping to writing the code. Hold your horses and think about the task at hand. Use a pen and paper or black board to clear up the biggest concerns. This will help clear any confusions. Draw some diagrams to help guide you.
You will be surprised that some little planning can save you from a ton of headaches.

Single Responsibility

I remember writing long functions in my c programs. I find some kind of joy in seeing the length of a source file reach the 300 milestone (don’t ask me why 300). The functions didn’t have a clear purpose. They were just there. When things work it is a great news but when the software doesn’t do what it is supposed to do, it is hours spent at the debugger.
Now I tend to write short methods/functions and classes. They are easier to manage. I don’t have to worry about many things at the same time.
Instead of having a method that initializes variables check for some conditions than do something when the conditions are met, I will split the method into smaller chunks that each have a specific goal.

Method before splitting

public void method(){
  Class1 a = new class ….;
  Class2 b = param.computeClass2(...);
  
  if (b.isSomething() && !a.isAnotherThing()){
    //Many lines
    result = ….;
  }else{
    // Many lines
    result = …..;
  }
}

Method After splitting

public void method(){
  Class1 a;
  Class2 b;
  initialize(a,b);
  if (conditionIsMet(a,b)){
    conditionMetRoutine(a,b);
  }else{
    conditionNotMetRoutine(a,b);
  }
}

The solution feels more elegant this way.

Abstraction And Encapsulation

What is Abstraction?

The essence of abstractions is preserving information that is relevant in a given context, and forgetting information that is irrelevant in that context.
– John V. Guttag

So using abstraction limits instead of using having to be concerned about every detail. Abstraction limits the quantity of detail we have to keep track of at a given moment.

Instead of worrying about database connection, SQL request and passing values around abstraction allows us to limit the scope so we just pass the values and the underlaying system handles the details without us needing to keep track of them.

What is Encapsulation?

In general, encapsulation is one of the four fundamentals of OOP (object-oriented programming). Encapsulation refers to the bundling of data with the methods that operate on that data.
Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them. Publicly accessible methods are generally provided in the class (so-called getters and setters) to access the values, and other client classes call these methods to retrieve and modify the values within the object.

Why bother?

Encapsulation allows us to control the access to an object internal fields making sure that it remains in working state and all rules regarding the object state are respected.

It is nearly impossible to have good abstraction while violating encapsulation. You can think of the abstraction and encapsulation as a pair. Abstraction is the goal the principle that we want to achieve while encapsulation is the tool we use to reach it.

Naming

I used to name things as temp and temp1 and before I know it I ended up with a tangled mess. I use temp1 instead of temp. I change a variable in a place and forget to change it in another.

Take time to name variables classes and routines. Providing descriptive names will make the code easier to read and understand thus easier to maintain. This will make sure that code written few months ago won't look like something from outer space.

Testing

Another practice that I started following is TDD. Following TDD practices makes for more robust code. Having a test suit ready will allow the detection of most defects as soon as they are introduced. Also the presence of the test suit boosts confidence removing the fear of breaking the system after refactoring.

Conclusion

The debugger provides some great functionalities. But if you find yourself spending so much time debugging. Try changing the way you write code. The time you spend debugging is time that could be used to make new features or refine your Software.

There are other practices that I started following that improved the general quality of code like commenting and following style convections.

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." - Brian W. Kernighan