Avoid just-in-case programming
“Just-in-case programming” refers to code that isn’t sure about itself - adding unnecessary defensive measures driven by fear and uncertainty rather than actual requirements.
Examples of just-in-case code
Section titled “Examples of just-in-case code”// "Just in case" the vector isn't emptyvec.clear();vec.push_back(item);
// "Just in case" it's not initializedptr = nullptr;ptr = new Object();
// "Just in case" someone passes nullif (data != nullptr && data->isValid() && !data->isEmpty()) { // Actually, what if data is valid but empty is okay?}
// "Just in case" we need thread safety somedaystd::mutex global_mutex; // Used everywhere "just in case"
// "Just in case" this variable gets corrupted somehowglobal_counter = 0; // Reset at start of every functionProblems with just-in-case programming
Section titled “Problems with just-in-case programming”- Obscures actual requirements - What are the real preconditions?
- Adds complexity without clear benefit
- Makes debugging harder - masks the real source of problems
- Performance overhead from unnecessary checks/operations
- Indicates lack of understanding of the code’s contract
The antithesis of intentional design
Section titled “The antithesis of intentional design”Just-in-case programming is the opposite of Make intentional design decisions. It’s driven by:
- Fear of failure
- Uncertainty about requirements
- Lack of trust in other code
- Cargo cult programming (copying patterns without understanding)
Better approaches
Section titled “Better approaches”- Understand your contracts - What are the actual preconditions and postconditions?
- Use assertions for debugging assumptions rather than defensive code
- Document assumptions explicitly
- Write tests that capture actual requirements
- Trust your interfaces - if they’re unreliable, fix them directly
Related
Section titled “Related”- Make intentional design decisions - The positive counterpart
- Write code that reads like the problem that it solves - Clear code reduces uncertainty