There are some simple rules we learn as we make our way through life. Sayings we pick up like, “an ounce of prevention is worth a pound of cure”, “one in the hand is worth two in the bush” these are shorthand ways of remembering and communicating important lessons we often learn though trial and error. Over the last 25 years, when I first began to write my own computer code, I have created some of my own words of wisdom whenever I am responsible for training someone for the position of Software Engineer. For me these thoughts and ideas are laws, I do not stray far from their instruction very often, and only when there are special, or mitigating, circumstances. I would like you to think of them more like principles learned from a lifetime of practice in the applied art and science of Software Engineering.
The highest, and most important of these principles is this.
1. Never allow the user to fail.
This I regard as the overriding principle of all the code I’ve written and designed.
This simple idea prevents much of the effort put into writing computer code today. It helps in writing code in a number of ways. The first, and most obvious effect this has on writing computer code is that test plans become much simpler. When I was learning to write software in college, my instructors told me that when I was working out an estimate for how long it would take to complete a computer application project, that often times it takes more time to test the software than performing the act of writing the application in the first place. This is because all of the conditions allowed within the software must be tested. A simple if/then statement within an application doubles its complexity and knowing the powers of two as any Software Engineer should, it doesn’t take many of these statement to create an almost innumerable number of test cases to test the code. If, however, the designer creates their model of the software in such a way that the user cannot, by act or omission, create a situation where they are unable to continue or produce a conflict that cannot be resolved, a lot of these complexity is reduced or even removed.
For example a situation I ran into back in the mid 90′s. I was working for a company creating software for Manufacturing facilities. within the application all the programmers were supposed to use the same window, or form, for the function of looking up an item number from the database. Restricting all of us to using this single form solved some problems, after all we didn’t have to code a different window for each module within the application for the same function, we didn’t want to “reinvent the wheel” yet another principle we can apply to programming. This solution, however, cause different problems later on. This window looked at all items within the database, it did not restrict the selection in any way, because if it did we could not all use it. So we had to make error messages when the user selected an inappropriate item from the database. As a user how would you feel hitting a button and asked to look-up an item that you are trying to make to fill an order? You select the item and are immediately told by the software that “You have selected an inappropriate item”. For me this is an absurd situation, if the item was not appropriate why on Earth would you allow the user to select it in the first place. It is as if the software has presented the user with a choice and after it has been made, it then begins to berate the user for not selecting the correct answer.
Another, less obvious, example I have seen far too many times is within the software written by others that allows what are called “free text” controls. In my opinion these should be used as sparingly as possible. If the data being stored by these controls are subjective in nature, like descriptions or names, then free text is fine, but if the nature of the data is relational, that is if they are intended to connect two ideas or provide a connection between two entities then they need to be provided to the user in such a way that they cannot enter an invalid or incorrect value. Recently I was asked to update a database that had a “location” field within it. The location field of the application was a “free text” field and everyone had a different name for their location. Users would often misspell or mistype the actual location that was supposed to be entered. I considered this a problem with the software’s design than with the user. I proceeded with fixing the problem not by treating the symptom and retyping in the correct locations for all the items in the table, but by redesigning the application and changing the way it allowed users to enter the location in the first place. Instead of a free-text field I placed a drop-down list control on the form. This restricted the user to selecting only valid choices from a list that was maintained in the database. Every location within the database was a valid location so no matter what location the user attempts to select there is no chance the user will select an invalid entry.
When a user cannot type in an invalid entry, when they cannot chose an invalid choice, when they are not allowed to navigate to a form or window they are not looking for then the need for error messages goes away. There will always be a need for error checking, but those errors that need to be checked should not come from users but from logical errors unseen by the engineer.













