TDD vs Defensive Programming vs Documentation Practice

I was just checking a legacy code 

Defensive Programming

If you are a believer of defensive programming, then most of your code will look like this:

Result method(arg) { 
if (arg == null) throw new IllegalArgumentException("Wrong parameter"); 
// Do stuff
}

There is one thing or two to say about this technique:

  1. You don’t trust people, much less programmers.
  2. You are convinced that this technique makes your code “bullet-proof” because it “protected” from external influencers.

If you are a defensive programming kind of guy (which I used to be) then (a) you should know that the world is much prettier when you are able to trust people, and (b) there are different points of view to consider.

Documentation Practice

Is defensive programming such a bad practice? No. Some people might say it is a document-driven practice as well. At the beginning of your public interfaces you basically say what your methods/services assume. If I put a validation statement on an argument before proceeding with the business logic, I am saying “This method only works when this/that valid input data is provided”.

So in the end it is it an ideal practice? No. This type of documentation is evident to the caller either through Javadoc (so long for our “documentation technique”) or whenever the method gets invoked. It is not a necessary technique when the caller is an actor inside the same module.

In the case of an external actor, you can see that unless the caller has access to your source code, he/she is not going to be able to know whether your method has some particular argument requirements.

TDD

Let’s talk about maintainability and testability. There are three basic problems to defensive programming:

  • Your code is hard to maintain. Your argument validation logic is mixed with the business logic itself. Anyone in charge of maintaining your code is going to have to process your endless argument validations first. You should try to avoid this by using a façade dedicated to these matters but sometimes it seems to make the code even less maintainable.
class MyClass ... {
Result method(arg) { 
// No more -> if (arg == null) throw new IllegalArgumentException("Wrong parameter"); 
// Do stuff
}
}
class MyFacade ... {
MyClass myInstance;
Result method(arg) {
if (arg == null) throw new IllegalArgumentException("Wrong parameter");
myInstance.method(arg);
}
}
  • Your code is hard to reuse. Unless you provide a Javadoc with your code, it is going to be very hard to reuse it. The Javadoc only has so much information. The rest is pure guessing.
  • Your maintainability activities have been increased. You need to include a Javadoc explaining your defensive programming rules, and keep these synced with the code itself.

TDD tries to solve this issues by making tests the first-class citizens of your application:

  • Your tests become your documentation. You don’t have to maintain Javadocs all the time (just the façade). Instead, your tests show any potential users of your code how a method/service should be used. What a valid or invalid argument looks like and under what conditions will the method/service fail. There is a side effect to this: you end up providing your client with a proof that your code is well tested and functional 🙂
Result method(arg) { 
if (!isValidUser(arg)) throw new BusinessException("You must be a valid user");
if (businessRuleBreaking(arg)) throw new BusinessException("Broke rule!");
// And so on...
}
  • Your maintainability issues in this matter are over. Your argument validations are split aside from your business tests. Most of your validations are now assertions of business rules as opposed to argument validations (your business rule tests will be part of your tests too!). Your codebase is now clean and free from overhead. 
class MyClassTest {
// set of business tests
}

class MyFacadeTest {
// set of argument-validating tests
}

In the end, using defensive programing (or fail-fast programming) is not as bad as it sounds, as long as you know when to use it. Also, make sure you use TDD and some patterns as a complement, they will make your life easier for sure.

Advertisements

2 thoughts on “TDD vs Defensive Programming vs Documentation Practice

  1. Pingback: TDD vs Defensive Programming vs Documentation P...

  2. Nice post. I would like to add that even though TDD has good points You can still write bad code even if you write your tests first. Indeed, you can write bad tests. This discipline depends on really hard work and professionalism.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s