|
Title: |
Good
Programming Techniques, 2001/01/04. |
|
Author: |
Moisés
Daniel Díaz Toledano |
|
Web: |
|
|
Email: |
|
|
Ad: |
Xcripter, Free
Database-Driven Internet Code Generator. |
Introduction.
What is an error? We could say a priori that an
error is a failure that is included in a program ruining the product and
affecting the client.
We can
also see it from another optics. When we develop software we try to provide
certain functionality to the user, if this functionality is not completed, we
can say that the software has errors.
These errors of those that are speaking, are
quantifiable errors (detectables) for the user, what takes us to the concept of
external quality of the software.
However, we still haven’t justified the purpose
of this article, why to make a quality programming? Because the external
quality of the software keeps a direct relationship with the internal quality
of the same one, that is to say with its structure and codification.
We all want to build correct, robust,
expandable and reusable software. We should be conscious that the best road to
achieve it, is in fact in making a quality programming.
They also exist other reasons of a lot of
importance to apply technical of good codification. As developers we cannot
forget that the code source is maintained and reused, with what we should take
care of our programming to facilitate these tasks.
The objective of the present article is to present
in a simple, informal and not too much ordinate way, some particular
techniques, as well as other general ones, for the exercise of a good
codification. Maybe you doesn't agree with some of these advice, but at least I
hope to make meditate the reader on them, that which without a doubt, will
bring quantifiable benefits to your developments.
1. - Nomenclature
A good part of the code is constituted by
identifiers of variables, functions, procedures and classes. Their election is
very important since they normalize the code, and help to understand the real
meaning of the actions that carry out.
It is very important to use a very defined
nomenclature in our code, since it increases the legibility and the semantics
of the same one vastly and makes simpler the work in team and the supervision
on the part of other people. Keeping in mind that the excesses are negative and
that therefore to specify rules for absolutely everything brings more problems
of those than it solves.
The broadly most extended nomenclature is the
'Hungarian Notation', with numerous defenders and detractors, each one very
armed of arguments. We can take out profitable teachings of this proposal that
presupposes that it is much more important to give information in the names of
the identifiers that to be able to read the code aloud.
One of the central ideas in this notation is
the use of prefixes that include information on the type of the identifiers.
This proposal in short has certain disadvantages in actual IDEs mainly to the
existence of tools that inform us as we go typing, about the different methods,
attributes, variables, etc available in
that particular context.
However, you can use postfixes to specify
certain information, in short information related with the variables valid
scope, topic that up to now has been not very treaty.
A possible recommendation would be the one of
using as postfixes 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 global scope.
modMain
Public oCnnG Ace
ADODB.Connection ‘This is only an
example!! Don't use global objects unless it is strictly necessary!!
Public Sub main
()
' some code
Sep oCnnG = New ADODB.Connection
oCnnG.Open "DSN=XX;SERVER=XX",
"XX", "XX"
'some code
Sub End
A small class example developed according to
the norms that are sketched along this article would be:
CFile
Option
Explicit
'Class
Coments.
Dim bConsistC Ace
Boolean
Dim sFilePathC Ace
String
Sub Public
Init(psFilePath Ace String)
Debug.Assert (Dir(psFilePath, vbArchive)
<> "")
sFilePathC = psFilePath
bConsistC = True
Sub End
Public Function sGetFileText
() Ace String
On Error GoTo
errCatch
Debug.Assert (bConsistC = True)
Dim iFile Ace Integer
Dim sTempText Ace String
iFile = FreeFile
Open sFilePathC For Input Ace #iFile
sTempText = input$(LOF(iFile),
#iFile)
Close #iFile
sGetFileText = sTempText
Exit Function
errCatch:
'Error code
End Function
2. – Big use of Assertions and Validations.
One of the pillars of a solid programming is to
be able to detect the errors quickly during the development to avoid that they
pass to the product that we give to the client.
The main mechanism to achieve this objective is
the widespread and profuse use of validations in the code to detect any non
valid use of our methods, classes, functions and procedures. I denominate this
‘Classes and Blocks Shielding.'
It is recommended as minimum to use them as
preconditions in our functions and procedures to validate: parameters, state of
the object, contextual states, etc. A general and abstract example could be the
following one:
Class
Option
Explicit
'Class Declaration
and Coments.
'Class-Scope
Declarations (remenber last character with 'C')
Sub Public
SomeProcedure (parameters list)
On error
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
Sub Exit
errCatch:
'error catch.
Sub End
A possible classification of the validations is
the following one:
q
Internal
Validations. They are written to capture erroneous states during the
development.
q
External
Validations. They are written to avoid erroneous states in the application that
had been produced in the interactions with external components to the
application (users, files, etc).
The only validations that will remain in the
final product are the external validations (mainly those concerning ones to the
interaction with the user), the interns have as main purpose helping us during
the development of the code.
In all ways, do I meet with certain frequency
with the question of why not to leave the internal validations? To say that
these ones imposes a high cost as for yield, and that they don't suppose any
help to the user. They help us vastly to develop a code of quality since they
detect inconsistent states and uses, indicating us that a problem exists and
not having to discover it the user.
The topic of the validations is so important
that if it is necessary we should maintain additional information in our
classes, modules, etc, to be able to make a stricter confirmation of
errors.
3. – Architecture reuse.
The structure of most of the applications 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, helping us of previous developments, and design patterns.
Making a small note on a specific question, we
can see that an important category inside the commonly used objects, refers to
those that go registering information that is originated in any part of our
application while this it is executing: the Log objects, the Reports, and even
some objects of global treatment of errors. These must be declared global so
that they can be used from any part of our application. It is also recommended that
they have a small and simple interface to avoid dependences with the rest of
the code.
modMain
Public oLogG Ace
CLogObject
Public oReportG ace
CReportObject
'.... BE CAREFUL,
don't abuses of global objects!!!!
Public Sub main
()
' some code
'Initialize oLogG and oReportG
'some code
Sub End
It is very important not to abuse of global
objects in our applications since they 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,
for what I repeat again, make these classes with a small interface, and that
can be only called from specific points of the rest of the code.
4. - Some Specific Advice.
They exist multitude of questions to keep in
mind when making a quality programming, here sketch some concrete topics that I
have found important:
q
Using error
managers. In any place of a program, errors can take place, but it is evident
that there are places with a bigger probability so that these happens. In a
principle we should make a wide use of error managers, but if it is not this
way, let us don't forget to code them in the code that makes use of resources
unaware to the own application: interaction with databases, protocols of
communications, files, etc. this way will avoid the famous "Runtime
Errors".
q
Controlling
the dependences of each class. A big inconvenience that we have when we want to
reuse a class in another project, is that with too much frequency we ignored
the necessary resources to make it work, that is to say how component it uses,
how other classes instance, etc. A simple mechanism to control this information
consists on including in the comment head of each class a line in which we
specify all its dependences clearly (components that it uses, classes that
instance, objects or global variables that it uses, etc).
q
Validating
the class consistency. It is important that we make sure that a class is only
used if it is in a consistent state. In VB it is not obligatory to call to a
constructor. We can also meet with classes whose instantiation process takes
several steps. Having a class variable that indicates us if the class is in a
consistent state (that is to say if it has been initiate with all the data and
references that needs) is something
that can save us many problems. In general I denominate to this variable
'bConsistC.'
q
Maintaining
the unity functionality. Building functions that make only one thing. This
makes easier reusing, building assertions,
understanding and communicating
them.
q
Not to incur in semantic unevenness. The code
basically is structured in blocks of two types: functions and procedures. We
have to attempt that in in each code block, the abstractions that we manipulate
are of the similar level.. This favors the creation of clear and free of errors
code, besides that it is easier of to understand. The opposite, is to incur in
what I call semantic unevenness.
5. – Some Other General Rules.
To conclude this not very orderly review on the
practice of the programming, we aim some general advice on the development of
quality code.
q
Code
Tracking. Let us don't scant efforts in contemplating like our code works.
Today in day most of the environments of developments allow to make tracking
task in a simple and rich way. It is incredible the quantity of errors that one
is able to find seeing work the code step to step.
q
Getting
code with a correct visualization. To make it more readable. This is gotten
formatting well the code: bled, color, structuring, appropriate size of lines,
correct extension in functions, procedures, classes, etc.
What is easier to
read?
1. -
Sub Public
Procedure(parameters list)
On Error GoTo
errCatch
Debug.Assert
(ValidateSomething ())
If bSomeCondition =
False Then
DoSomething
Else
For each object in
colObjects
If
bSomeOtherCondition = false then
DoOtherThings
End If
Next
End If
Sub Exit
errCatch:
MsgBox
Err.Description,.......
Sub End
2. -
Sub Public
Procedure(parameters list)
On Error GoTo
errCatch
Debug.Assert (ValidateSomething ())
If bSomeCondition = False Then
DoSomething
Else
For each object in colObjects
If bSomeOtherCondition = false
then
DoOtherThings
End If
Next
End If
Sub Exit
errCatch:
MsgBox Err.Description,.......
Sub End
q
Building
consistent interfaces. It is important to build well-known environments for the
user, for what we should not fear to copy the style of applications of common use.
It is important to use visual structures that reflect the real structures that
the user is managing. This makes the user to forget that an application exists
between him and its data.
q
Be
centered in important things. Not all the options of a program have the same
importance, with what we should not forget to make sure that the really
important things works correctly.
q
In a
general way, not to sacrifice clarity for speed. The speed depends basically on
the architecture and technology used in an application and not of concrete
details that we have developed in our program.
Bibliography:
·
Maguire,
Steve. “Writing Solid Code”. Microsoft Press (1993).
·
Gamma,
E., Helm, R., Johnson, R., Vlissides,
J. “Design Patterns. Elements of Reusable Object-Oriented Software”,
Addison-Wesley, 1995.
·
Meyer,
Bertrand. “Object-Oriented Software Construction, 2nd Edition”. Prentice Hall,
1999.
·
Hamilton,
J.P. “Fifty Ways to Improve Your Visual Basic Programs”, http://vb.oreilly.com/news/vbshell2_0901.html
.
Moisés Daniel Díaz, Software
Engineer.
Moisés Daniel is a Software Engineer that currentlyworks for Andalusia Government. He is interested inObject Oriented Analysis and Design, Pattern OrientedDesign, Xml Technologies, Information Systems, NeuralNetworks, and... writing, reading, composing music,photographs, and much more. Moisés Daniel wants to develop small applications andarticles that can provide an useful aid to developersand let people make projects that before werereserved for teams.
Email: moises@moisesdaniel.es