Blanket term for various practices increasing code stability once the code is in production. Defensive programming defends against the currently impossible.
Idioms that have DefensiveProgramming as the primary effect:
Idioms that have DefensiveProgramming as a side-effect:
See also: OffensiveProgramming
Pro
Defend against the impossible, because the impossible will happen.
Critical sytems will not fail, but rather try as hard as possible to do the RightThing.
DefensiveProgramming aids the future maintainer of the code.
Q: How?
A1: Functions will do what their name suggests, even if newly introduced parameter values were not used before.
A2: Things only break where they must.
Con
Why defend against the impossible if it can't happen?
Counter: Impossible things become possible when new people join the team, and when code goes into maintenance.
Counter2: Humans make anything possible when it comes to errors.
It increases the mass of the code, which will now have more inertia and be harder to change.
It may hide bugs instead of making them visible, if misapplied. See OffensiveProgramming and OffensiveDefensiveProgramming.
DouglasAdams said it best: The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong goes wrong it usually turns out to be impossible to get at and repair.
I am currently working on a system about to go into production. We have a number of TroubleReports? that needs to be resolved first, however. The system consists of a number of networked nodes working in cooperation, and the trouble reports I have been looking at is usually along the lines of "unit X swallow packet of type Y under conditions Z". I have not looked at many of these problems yet, but the ones I have has been due to the common misunderstanding about DefensiveProgramming. For example, a packet was silently ignored because it was in the wrong format.
Misappliances of DefensiveProgramming are usually hard to track down as they take effect as just missing behaviour, and not a loud and visible error message. The idea of DefensiveProgramming is good, but it is often misapplied. I therefore suggest using the term OffensiveProgramming instead.
If a bad packet was silently ignored by some process, rather than an exception being thrown, then it would appear to be the opposite of what is being talked about here. Defensive programming means raising errors loudly (via assertions usually) whenever something is not perfectly within specification (even things that seem very unlikely to ever happen).
Dunno if this is the right place. But I have an issue like this.
When you're forced to deal with error conditions by explicit exception handlers, you're often inclined to do something that makes sense locally, but doesn't in a wider context. For example, you catch a thrown exception, and handle it in a way that doesn't break execution. But later on, someone tries to re-use the code and your exception handling is now ExceptionHiding?.
I prefer it when things just break.
I prefer it when things just break.
Another consequence of ExceptionHiding? is that related systems can easily become dependant on your system not reporting invalid input/error conditions. I'm currently working on expanding the scope of a legacy program which 'eats' bad input. The result of this is that refactorings and improvements in a subsytem tend to break the program. Not because the subsystem that I've changed don't fullfill its' duties, but rather because many of the other sub-systems in the app are reliant on not receiving exceptions when they spew bad output. Rather than being able to make an isolated refactoring, the changes must either be BugCompatible? with the legacy system, or the dependant systems must also be fixed. This has lead to constant headaches with testing and use because new problems are often hidden by the handling for the other legacy systems, leading to frustrating bug hunts. I also see (on the horizon), a good deal of work to go back and find all the cases where we had to ignore invalid input to be BugCompatible? and remove them.
Personally I've always thought of DefensiveProgramming as being extra cautious with situations that should raise exceptions or lead to errors further on in your function. Checking 'If x <= 0' instead of simply 'If x = 0', or checking for both overflows AND underflows. -- AaronCumming?