5 reasons that over defensive programming is not great design
I have encountered some good developers that spend an inordinate amount of time putting defensive mechanisms into their code: hiding, sealing, protecting, checking, throwing, obscuring, and complicating. "I just need ten more hours to make this object inaccessible." And, "the solution is to make everything static."
#4: Too much complexity
All of this adds complexity. It adds surface, design and cyclomatic complexity. While there is a certain amount of essential complexity built into any problem space, each little bit of unnecessary complexity adds conceptual weight.
#3: Not as testable
The implication of sealing, protecting, obscuring, and complicating: code is less testable. One irony in all of this: these good but over defensive programmers never seem to write any tests.
#2: Inhibits change
Defense driven development it is a different approach: one that does not embrace change albeit. You need simple, testable code to embrace change. This one could be #1. In some domains, the ability to adapt to change is the key to being #1 (and sometimes survival).
#1: It is hubris
It is like saying, "I have thought of everything." You can't extend or modify this kind of code. Those that spend time sealing, protecting, obscuring, and hiding, are making it difficult for people to extend their code. There is no framework or open architecture. It is closed without being open. Realize: you can't think of everything.
Now, don't take this too far—in a way that is the point. A small amount of defensive programming is not only good, but necessary. But taking it too far creates too much distance.
At some point you have to score, so don't let your lizard brain get in the way.
Code is design. Over defensive programming is not great design.