Defensive programming or paranoiac programming?
Recently discussing design and programming with an external programmer, he explained me his approach of defensive programming.
But before going in detail of his explanations, Wikipedia help us to define the defensive programming:
Defensive programming is a form of defensive design intended to ensure the continuing function of a piece of software under unforeseen circumstances. The idea can be viewed as reducing or eliminating the prospect of Finagle's law having effect. Defensive programming techniques are used especially when a piece of software could be misused.
We understand that it is one "mind set" which is excellent, because it allows us to deliver less fragile code. Furthermore, this way of seeing things is in direct link with the creation of unit test (the TDD or TLD (Test Last Development) but I will not go into this debate here? J).
Here is an illustration of its vision (of the developer)
The developer explained me that it is essential to put of the management of exception in Service123 but also in all the functions of all the classes of the utilitaire assembly. Also, that it was imperative to put some validation of parameters everywhere, but also in the classes marked as internal, thus not visible and usable from everything outside of the assembly which contains them.
It is at this moment that I said to myself: "Can the defensive programming in its limits can quickly become of the paranoiac programming?" I give some explanation, the try catch and the validations have impacts at several levels among which on the performance and the code’s readability to name only these.
I, above all I try to identify the entry points of my components which can bring irregularities in the functioning of my system. Also, I try to identify the places where I have a dependence towards contexts outside my application (Web service, database, physical file) because these dependences can weaken my component or class. The rest I trust my unit tests to validate my non-regression and the smooth running of the features of my classes.
Thus if we return to our example, the entry points of this micro-system are ProduireDoc of Service123 and CreerPatente of the ComponentA class. These two places should validate their parameters. Since, Service123 depends on ComposanteA thus, then Service123 should manage exception for various reasons (masking interne exception, management client’s experience, logging, etc.).
Then, the function FaitXYZ of ComposanteB should not make validations on what the component ComposanteA passed as parameters but only the validations of the logic that it takes care and it’s the same thing for the exceptions, it should be captured by the entry point CreerPatente of ComposanteA.
And you, how do you manage your programming, are you more a defensive or paranoiac type?