Good programming

The following are the fifteen commandments of good programming. They are an imperative to having a smooth time after initial deployment of your program at the customer’s site. Follow these steps and you will have much lesser work maintaining the software that you have made.

1) You shall not start coding without having a generic database access class or function properly tested and found to be good.

You simply cannot write more than two or three code units without having a database access class or function. If you don’t have a database access class or function and are writing an application, it is like reinventing the wheel in every code unit!

2) You shall not start coding without having a system that logs all important tasks performed. In particular, you shall not start coding without having a class for logging to a file all the database queries that are executed, whether or not they fail or even whether or not you feel today that they are important.

If your application does anything significant with a database, it most likely that the actions performed from the User interface will correspond nearly one-to-one with the database queries your application runs. So, to keep track of actions performed on your system, you must log all queries, even all select queries. Having all the queries display in a text log will be an immense help while debugging a complex user interface screen or page with many controls. For example, if your user interface is getting the wrong values, the select queries will tell you what your program is looking for instead of what it should be looking for.

3) You shall not start coding without a source code control system or a source code versioning system.

The importance of this component cannot be stressed enough. If you have about 10 User interface screens and about 5 code units, each with about 500 – 1000 lines of code, you can hardly expect to remember, even over a period of a few days. what changes you made to which unit to bring about so-and-so minor change in the functionailty of the program. Say, you want to undo a particular change. Say you want to copy a particular change from one unit to another. In all these scenarios, if you do not have a source code versioning system, you are more or less lost – in your own application. You will have saved yourself endless frustration and confusion if you use a source code versioning system.

4) You shall backup your work daily to a place other than your backup directory on your machine, preferably, to an Internet file store or a Compact Disc or you email account.

This is to prevent your work from getting lost due to accidental deletions, computer crashes and viruses.

5) You shall write technical documentation of the code as you code.

If the construction cycle (coding) takes up a month or two and you have decided to write technical documentation after that period, you will regularly find your self wondering why you wrote a particular piece of code the way you did. The thinking that goes behind the code is obvious at coding time, but is forgotten, and so, is less obvious after two months.
UPDATE: btruelove is very right about not keeping technical documentation separate:

“In my experience it is much better to sufficiently document your actual code rather than create another source of documentation that will slip through the cracks and get rapidly out of date.”

6) You shall not visit the customer with a running copy of your program which you have not tested thoroughly.

When the customer enters a few arbitrary values, or if he is smart, a few tricky characters, and your program hangs, or does something silly, it hardly looks good. Any special functional conditions that have been discussed out during the requirements phase, must necessarily make it into the demonstration to the customer. The customer often does not have a full understanding of all the possibilities that arise out of a particular features he has suggested. When you have all your functional parts working properly, he then starts to think about the undiscussed, but fairly relevant, possibilities that arise out of the feature he has requested. So, it is important that you show him all the functionality that has been discussed till that time. If not, it will mean more meetings, nothing else. The exception to this rule is when you simply meet the customer to show him how many lines of code you have written, to assure him that work is really going on in full swing on his application. Then, you are not bound to show him all the functionality. Also, when you want to clear out basic things about user interface or functionality, you can show incomplete work, preferably a prototype, to get more inputs.

7) You shall not visit the customer before you have resolved all minor or trivial bugs that you know of.

It gives a poor impression to the customer if you claim that so-and-so feature works and a bug pops up in the elementary functionality of your program. It is plain embarrassing.

8 ) You shall not visit the customer without a set of complete and coherent data.

The customer often has no clear or complete idea about what he wants. When you have taken the pains to make a running, tested program why not show him all the functionality that you have put into your program. You must at least have all the data that enables you to show him all the functional checks that you have put into the program. Also, you need to give the customer some additional data with which he can play around with your program and get used to it. The more he uses your program, the more he understands his requirements, and the clearer he is in asking for more functionality.

9) You shall not go live without a generic, well-tested database export and import utility. If you choose to use an external utility you shall not go live till you have tested that utility thoroughly with your specific data.

If something goes wrong and you need to backup the entire database to simulate the error on your development machine, you need some method to duplicate the state of the application. The obvious way is to have a database export utility. Maybe you need to add a few tables for a newly requested part. You need to pick up data from existing tables, modify it and add it to these new tables. And there are about 500 records in each of the source tables. Naturally, you need a database import / export tool.

If you are using a generic tool supplied by your database vendor or a third party, it is naturally not designed to handle your particular needs. So it needs to be tested thoroughly to ensure that all parts of your database can be imported /exported with ease. A custom tool is always preferable. Situations where a generic utility is useful are when the data is too huge or complex for you to develop a component for.

10) You shall keep in mind that the screen resolution of your customer’s computer can be different than the screen resolution of your development machine.
The UI of your application must either be generic (for example, standards-compliant HTML which shows up more or less the same on all browsers, or say cross-platform look-and-feel like Java uses) or at the very least, must look good on your customer’s machine. It’s not good to choose the second option because sooner or later, the customer will change his computer screen, his operating system, his screen resolution etc. So, UI that is flexible is good.

11) You shall test your GUI application with both keyboard (shortcuts, navigation) and mouse, and deliver to the customer only when you have tested both ways and found the behavior satisfactory.

Some people prefer using the mouse, while others, the keyboard. Using the Tab key is a widely used practice/standard for keyboard users. So do not code for only one of them, both ways should work fine.

12) You shall not show the program to the customer without having a proper error handling mechanism in place. Any unexpected error shall not come up in its native programming language format, but shall show up only as a discreet message like “An Internal error occurred. Please report it to your program vendor”

Depending your programming language and platform and the error, an unexpected error might cause a cryptic error message or even cause the machine to crash or hang. Error handling in every code unit sees to it that only well-behaved errors (that your customer can understand) are shown.

13) You shall code specific error messages in preference to general ones.
Instead of error messages like “No records updated” and “Unable to insert record”, you shall code error messages like “Could not update bill totals for product XYZ” or “Failed to update the value of Bill Amount”. When a bug comes up in your application six months after it has been deployed, it is much easier to see what went wrong if you have the exact business logic error reported by the error message. If the code unit updates 5-10 tables, a lucid and explanatory error will immediately tell you which table was the source of the problem. Of course you do not put table names in error messages, but distinct error messages and error codes make for quick debugging.

14) You shall, wherever possible, keep redundant mechanisms to repair operations that have not completed due to unexpected errors.
For example, in an inventory application, if the stock does not get automatically updated on generating a bill, a separate screen should be present which makes it possible to manually update the stock as well. Although this example is not the best, what is meant is that if there are two ways of doing the same thing, it is that much easier. However, this should not be the way you design the application – that is, allowing for some part of your program to not function. If your application does not naturally lend itself to such repeating functionality, do not do it. Another thing that you can do is have a data integrity checker module which when run as a maintenance utility, makes a report of any inconsistent data and mails you the report. This is for the case where accidental deletion of records ( or maybe a bug) cause data from related tables to be inconsistent. Again, such situations should not arise if the program is written correctly.

15) You shall first think out and design the application and then start coding .
In a book by Schneider, Weingart and Perlman, it is recommended that, if the entire task of programming is made up of 10 stages, then actually coding the program begins at step 6. This however does not refer to the time allocation for each stage. Most likely you will finish the first five steps in 10% of the entire time required. The earlier steps include concept (idea) of the program, design, etc. What they mean is that unless you have the architecture of the program designed out, do not start coding. It will only mean a lot of rework. If you are okay with rework, go right ahead and code. Designed applications are much easier to maintain than applications written in think-as-you-code fashion.

If you are a sincere and dedicated programmer, you do not need to bother over these points, you will have taken care of these yourself. These are just some practices to follow and some checks to made as part of a routine which ensure that maintenance of your program – the part that follows the coding and deployment, so that it becomes a smooth affair.

Disclaimer: These are my personal suggestions, made out of my experience, you are not guaranteed success or anything by following these.

Copyright: The author holds the copyright for this article. You may copy and use this article, but not modify or call it your own or anyone else’s. You must mention that you got this article from this site.

%d bloggers like this: