Good Programming Techniques

Author Moisés Daniel Díaz Toledano
Web http://www.geocities.com/moisesdaniel01
Email moisesdaniel01@yahoo.es

Introduction

What is an error? We could say that an error is a failure that is included in a program. It ruins the product and affects the client.

Let's examine it from another perspective. When we develop software we try to provide certain functionality to the user, if this functionality is not provided, the software is said to have errors.

The errors, we speak of, are quantifiable (detectables) to the user, and thus take us to the concept of external quality of the software.

Nevertheless, we still haven’t justified the purpose of this article: what is the reason for writing quality code? The reason is simple: the external look & feel of the software has a direct relationship to its internal quality, that is to say with its structure and design.

We all want to build correct, robust, expandable and reusable software. We should be conscious that the best way to achieve it is in fact to practice quality programming.

There are a great many other reasons why one should apply good coding techniques to software design. As developers we cannot forget that the code source is maintained and reused, thus we should take care of our programming to facilitate these tasks.

The aim of this article is to present in a simple, informal way to write good code. In addition, some particular techniques, as well as other general ones, will be presented in order to show good coding skills. Even if the reader disagrees with some of this advise, I expect to make the reader think about it, which undoubtedly will bring quantifiable benefits to your developement.

1. - Nomenclature

Good code is constituted by identifiers of variables, functions, procedures and classes. The selection of the names/identifiers is very important since they normalize the code, and make it easy to understand the real purpose of the code.

It is very important to use a very defined nomenclature in our code, since it increases its legibility, while making it vastly simpler to work in a team environment or to supervise employees. Keep in mind not to go overboard and specify rules for absolutely everything, because it will create more problems than it solves.

The most broadly used nomenclature is the 'Hungarian Notation', with numerous defenders and detractors, each one very armed with tons of arguments. Whether we like this nomeclature or not, it basically states that it is much more important to add information to the names of the identifiers than to be able to read the code aloud.

One of the central ideas in this notation is the use of prefixes that include information about the type of the identifiers. This proposal has certain disadvantages with regard to its usage in modern IDEs, mainly due to the existence of tools that inform us, as we type, about the different methods, attributes, variables, etc... available in that particular context.

However, you can use suffixes to specify certain information, for instance, related to the scope of the the variables: a topic that up to now has not been discussed that much.

A possible recommendation would be to use suffixes in the identifiers to indicate the valid scope of certain variables, using the following characters: 'C' for the class variables and 'G' for the objects or variables of global scope.

Public oCnnG As ADODB.Connection

Public Sub main()
    ' some code
    Sep oCnnG = New ADODB.Connection
    oCnnG.Open "DSN=XX;SERVER=XX", "XX", "XX"
    'some code
End Sub	

A small class example developed according to the norms described in this article would be:

CFile
Option Explicit
'Class Comments.
Dim bConsistC As Boolean
Dim sFilePathC As String

Public Sub Init(psFilePath As String)
    Debug.Assert (Dir(psFilePath, vbArchive) <> "")
    sFilePathC = psFilePath
    bConsistC = True
End Sub

Public Function sGetFileText() As String
On Error GoTo errCatch
    Debug.Assert (bConsistC = True)
    Dim iFile As Integer
    Dim sTempText As String

    iFile = FreeFile
    Open sFilePathC For Input As #iFile
    sTempText = Input$(LOF(iFile), #iFile)
    Close #iFile

    sGetFileText = sTempText
    Exit Function
errCatch:
    'Error code
End Function


2. – Ample use of Assertions and Validations.

One of the pillars of a solid programming is to be able to detect errors quickly during development so that we avoid having to deal with them once the product is shipped to the client.

The main mechanism to achieve this objective is the widespread and extensive use of validations in the code to detect invalid use of our methods, classes, functions and procedures. I call this ‘Classes and Blocks Shielding.'

I recommend, as a bare minimum, to validate the following entities in our functions and procedures: parameters, state of the object, contextual states, etc. The following piece of code is an abstract example of the above rule:

Class
Option Explicit
'Class Declaration and Coments.
'Class-Scope Declarations (remenber last character with 'C')

Public Sub SomeProcedure(Parameters_List)
On Error GoTo errCatch
    'Class state Validation (class variable and objects related with this class!!).
    Debug.Assert (bIamConsist() = True)
    Debug.Assert (oClass2C.State = adStateOpen)
    'Parameters validation, for example:
    Debug.Assert (bIsValidParam1(param1) = True)
    'If It is required Global state validation, for example:
    Debug.Assert (DatabaseConnectionG.State = adStateOpen)
    
    'some code
    Exit Sub
errCatch:
    'error catch.
End Sub

We could classify the validations as follows:

The only validations that will remain in the final product are the external validations (mainly those that deal with user interaction). The main purpose of internal validations is to aid us during the development cycle, and thus are preferably removed from the shipping product.

Quite often I am asked why I don't simply leave the internal validations? The answer is that they impose a high processing cost while providing zero benefit to the user. They help us enourmously, however, to develop quality code by indicating to us that a problem exists.

The topic of the validations is so important that if it is necessary that we should maintain additional information in our classes, modules, etc, to be able to make a stricter confirmation/validation of errors, than so be it.

3. – Architecture reuse.

The structure of most of the applications we create is very similar. We can observe that certain objects exist in almost all our programs. It is important to develop a clear and simple architecture in our application, aided by reusable pieces drawn from previous develpment projects, and design patterns.

For example, at a minimum we should be including in our common reusable framework certain types of support objects, such as registration and logging objects, error handling objects and possibly even some reporting support objects too. Typically we would want to declare some of these objects globally so that they can be used from anywhere within the application. Its also recommended that their interfaces are kept simple and uncluttered. Its very important that these objects are not tightly coupled to other pieces of the project - this makes them more reusable.

modMain
Public oLogG As CLogObject
Public oReportG As CReportObject
'.... BE CAREFUL, don't abuse global objects!!!!
Public Sub main()
    'some code
    'Initialize oLogG and oReportG
    'some code
End Sub

It is very important not to abuse global objects in our applications since this also can diminish the reusability of our classes (we make them much more interdependent). In any design one of the commandments is to develop modules, classes, components, etc highly decoupled with the rest. To that end, I repeat again, build these classes with a minimal interface, so that they are easily called from specific points of the rest of the code, and so that it is easy to 'plug-in' a different class instead of the first one.

4. - Some Specific Advice.

There are always a multitude of concepts we should keep in mind while building quality software. Here are some ideas that I have found important:

5. – Some Other General Rules.

To conclude this not very orderly review on the practice of programming, I'll give some general recommendations on techniques that can help you develp quality code.

Bibliography:



Moisés Daniel Díaz, Software Engineer.

Moisés Daniel is a Software Engineer that currently
works for the Andalusia Government. He is interested in
Object Oriented Analysis and Design, Pattern Oriented
Design, XML Technologies, Information Systems, Neural
Networks, and writing, reading, composing music,
photographs, and much more...
 
Moisés Daniel wants to develop small applications and
articles that can provide useful examples for developers
and help individuals create projects that before were
reserved only for teams.
Email: moisesdaniel01@yahoo.es
Web: http://www.geocities.com/moisesdaniel01