Tuesday, February 19, 2019

Points you should take care of for a defensive programming

During my career as an Android programmer I have noticed a lot of programmers don't consider - or know - the concept of Defensive Programming while writing their code, which leads to their code generating unexpected and unhandled bugs, either during testing phase or even after publishing their applications.

As a programmer you should - or al least do your best to - avoid your app crashes in users hands. As for my self, I could - to some extend - accept an app with some misfunctioning feature and wait for the developers to fix it; but I could never accept an app that crashes and will immediately uninstall freeing some memory for a better developed app.

What is Defensive Programming?


If you looked up the term "Defensive Programming" you will find this according to Wikipedia's:

"Defensive programming is a form of defensive design intended to ensure the continuing function of a piece of software under unforeseen circumstances. Defensive programming practices are often used where high availability, safety or security is needed."

In other words, "Defensive Programming" is technique to develop a software that doesn't crash if the users performed an unforeseen action or received some unexpected sort  of data. Using these techniques you can ensure the continuity of your software - or otherwise gracefully handle exceptional conditions - while you find out a solution for the aroused issue. BUT DOESN'T CRASH.

Below are some points to take into consideration while developing:

1) Try and catch


try{
}catch(Exception ex){
...
}

A lot of developers  don't consider using try & catch blocks unless forced by an IDE error alert. Well, you should!!

Example of cases you should use try & catch with are:

a) Whenever you write a code that involves data types transformations such as parsing Integer to String and vise versa as this might throw "NumberFormatException".

Also handling JSON strings and mapping them to other Objects.

b) Code that will perform actions away of your main thread and return back with response, such as communicating with remote servers over HTTP or even your local SQL database, where you don't have a full control or knowledge of the coming response.

Note: you should not treat "try & catch" as a final solution for the problem, however; it should be considered as a temporary plug to avoid crashes while you investigate and handle the issue in a better way.

2) Null checks


if(object != null){

}

"NullPointerException" is the most popular and most occurring exception. Don't underestimate the above simple null check whenever you doubt your variable/object might return null. Due to inability to distinguish nullable and non-nullable reference types. Because of that, many programmers code defensively against them. So much that in many projects almost each public method and constructor is populated by this sort of checks.

If allowed to slip through, nulls can lead to obscure errors down the road. But you still can significantly reduce the number of such validations.

One way to do that is the Optional<> operator introduced in Java 8.

3) Variables initial values


private String name = "";

Unless intended, always set initial values for variables you declare to be set in a later stage in your code. For example: a user name you are fetching from an API call, to avoid exceptions such as NullPointer and NumberFormat if this variable failed to get set due to a failing request.

4) Switch default case


switch(number){
          case 1:
             ...
          break;
          case 2:
             ...
          break;
          case 3:
             ...
          break;

          default:
             …
}

Don't forget to add a default case if you doubt your variable might be assigned a value not handled in your cases.

5) IDE code warnings


Always check lint warnings raised by your IDE and solve them whenever you can. Your IDE can warn you about various aspects in your code:

- Possible NullPointerException
- Unchecked type conversion

Conclusion


If you intend to publish an application to users you should consider the fact that users might use it in a way you didn't cover in your test scenarios leading to the possibility of crashes.
You can reduce this possibility by following simple defensive rules while developing your code, that will help keeping your app functioning under unexpected conditions and of course keep your users satisfied.

No comments:

Post a Comment