|When you're driving down the street, you presumably always err on the side of caution. When waiting to exit a junction or roundabout, you wait until it's safe to pull out into the traffic, even if the approaching car may be indicating to turn into your junction. As you approach a junction and you see a car waiting to pull out, you instinctively keep a cautious eye open in case the car suddenly decides to pull out.
When you learn to drive a car, you are taught to drive defensively, and most people continue to drive this way throughout their lives. Expect the unexpected, never assume anything or take anything for granted. When we drive we assume that everyone around us can potentially and possibly make mistakes.
By the same token, Defensive Programming works along the same lines. Your code should always expect the unexpected, and never make any assumptions. This is the he(art) of Defensive Programming.
Wikipedia:Defensive programming is a form of defensive design intended to ensure the continuing function of a piece of software under unforeseen circumstances. Defensive programming practices are often used where high availability, safety or security is needed.
Never trust input from a user or external application. Both of these are completely outside of the control of the programmer, and so therefore you have absolutely no control over what will be input. If you don't control the input, then you must assert for its validity.
Never assume the user will enter valid input. In fact, it is far safer to assume the exact opposite. Assume the user will enter complete garbage and ensure this garbage is rejected by the application with a suitable error message given. This already immediately makes the application more robust by protecting it against users entering garbage for input. If the user is supposed to enter a date, ensure that this is all they can enter. If the user is supposed to enter a number, ensure this is all they can enter. I'm sure you get the idea. The same rule applies to inputs coming from external systems. If your application integrates with another system, ensure that any inputs are stringently asserted beforehand.
Assert() statements to ensure the inputs meet the expected types and values, and only proceed if they do. Otherwise throw a meaningful error. Be as strict as necessary. Only values that meet the exact format expected of the application should be allowed through. Everything else should be rejected. Instead of asserting for what is invalid, instead assert for what is valid, and process accordingly. There is probably a much longer list of ways that something can be wrong, than there is for ways in which it can be right. So it is probaby better to assert for those cases.
Before consuming a resource, ensure that the resource is valid. For example, when accessing data from a database connection, check that the database connection is valid and is open.
SqlConnection connection = new SqlConnection("myDatabaseConnectionString");
SqlCommand cmd = new SqlCommand("myStoredProcedure", connection)When reading values from a database, don't assume that there is any data and don't assume that the data is valid. There may be no data or the values returned may be null for example.
SqlDataReader reader = cmd.ExecuteReader();
string firstName= reader["firstName"]; Don't assume that a variable contains a valid value, or that is has even been properly initialised.
decimal funds = money.GetFunds(); Defensive Programming is a minsdset as much it is a programming paradigm. Assume nothing, assert everything, expect the unexpected.
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare
modified 29-Jun-17 5:03am.