Funding for 'IT Lab' Project, Phase 1: Progress of sticker sales. Purchase a sticker to help us reach our target.Updated: 2010-02-28 11:53
How to write better Code

As programmers we do coding every day. We use different programming languages, IDEs for this purpose. The programs we write may be very time critical enterprise applications or a simple program to add two numbers. But have you ever stopped for a while and thought about the quality of the code that you have written? Have you ever wanted to improve the way you write programs?
Why we need better code
According to many researches, software maintenance is the most costly
stage of a software lifecycle. Typically it consumes from 40 - 80 percent of
software cost. Most of the times maintenance is done by new set of developers
who may or may not have much experience in the industry and with the software
they are maintaining. If the code is unreadable and difficult to
understand, maintenance becomes programmer’s nightmare. Code
become brittle and we introduce few more bugs when trying to fix one. Eventually
we come to a point that writing a new system from scratch is much easier than
fixing the old one. But if we do not understand the root course of
this mess we may end up creating another mess than solving the first one.
So what is the
problem with our software? Just writing some functional code does not make us
better programmers. Most of the time we are just interested in writing code to
get something done, we do not care about other important facts such as
readability, maintainability, or extendibility of our code. We are
thinking that putting bit more time to make our code more readable is a waste of
time. But it is far from the reality. Putting bit more effort to make our code
readable and extendable will save lot of time and effort in the long run.
Purpose of this article series is to help you improve your skills of writing high quality software. First of all let’s understand few characteristics of good Software.
Characteristics of Good Software
MAintainability
Specifies the ease of
which changes can be made to satisfy new requirements or to correct
deficiencies. One thing we can be 100% sure of is that requirements can change
over time and new requirements can come up after we deliver the software to the
client. Well designed software should be flexible enough to accommodate
these future changes. As I explained earlier maintenance is the most expensive
phase in software life cycle. Quite often the programmer responsible for writing
a section of code is not the one who must maintain it. For this reason, the
readability of the code and quality of the software documentation significantly
affects the maintainability of the software product.
Correctness
Is the degree
with which the software adheres to its specified requirements. At the start of a
software life cycle, requirements for the software are determined and formalized
in the requirements specification document (SRS). Well designed software should meet
all the stated requirements. While it might seem obvious that software should be
correct, the reality is that this characteristic is one of the hardest to
achieve. Because of the tremendous complexity of the software products, it is
impossible to perform exhaustive execution-based testing to insure that no
errors will occur when the software is run and will provide intended
results.
Reusability
Describe the
ease of which the software or components of it can be reused in developing new
software. By reusing existing code fragments/modules, we can
develop more complex software in a shorter amount of time. Reuse is already a
common technique employed in other engineering disciplines. Like we can usenuts
and bolts to build different things we can use software components like ‘fast
sorting algorithm’ we developed in some other software in future. Even though
this sounds simple lot the thinking ahead and use of design principles is
required to achieve this.
Reliability
Is the frequency and
criticality of software failure, where failure is an unacceptable effect or
behavior occurring under permissible operating conditions. The frequency of
software failure is measured by the mean time between failures (MTBF).
Acceptable MTBF vary from one software to another based on the context on which
it is used. For example life critical
software systems such as Life Support Systems in an ICU or Air Traffic Control
Systems we can’t expect any failure; MTBF should be zero. But for
an application like web browser we can accept few failures but not frequent.
Achieving very high reliability can be quite expensive.
Portability
Is the ease of which
software can be used on computer configurations other than its current one. In
today’s context this is really important because users use different types of
hardware and operating systems. If we want to reach all of them we should limit
the dependency of our software with specific hardware or OS.
Portability is not only important for desktop applications;
it is similarly important for web
applications as well. Web applications should support wide verity
of browsers; at least few common browsers like IE, Firefox, Safari, Opera and
Chrome.
Efficiency
Describes the
degree in which the software fulfills its purpose without wasting resources.
Efficiency is really a multifaceted quality characteristic and must be assessed
with respect to a particular resource such as execution time or memory usage. If
your application is a resource hog, users will not like to use it. One
measure of efficiency
is the speed of a program's execution. Another measure is the amount of RAM the
program requires for execution. Often these two measures are inversely related,
that is, increasing the execution efficiency causes a decrease in the space
efficiency. This relationship is known as the space-time tradeoff. When it is
not possible to design a software product with efficiency in every aspect, the
most important resources of the software are given
priority.
How to achieve all
these characteristics is our challenge as software developers. Yes it not an
easy task, we’ll have to put bit more effort at the first but they will
definitely pay off at the latter stages of the development. Writing good, clean
code requires lot of discipline as well; it is like a drawing a painting on a
canvas.
During this series of articles we’ll discusses different aspects related to writing better code. So let’s get started…. (Even though the sample codes are written in Java you can apply these concepts without any language barrier.)
Coding Conventions
I
think this is the starting point of writing readable and maintainable code,
and
it is relatively
easy to follow as well. In today’s context Software development is never an
individual effort; rather it is a team effort. Imagine how it would look like if
10 developers in a project use 10 different coding styles? It would be a
nightmare. Each individual will have to put extra effort to understand the
code
written by her colleagues. But by following single style or standard we can
illuminate that and our code will look like the same, doesn’t matter who written
that code. There are different conventions developed by experts for different programming languages. I’m not going to explain coding conventions deeply here since they differ from one language to another. Following are some of those conventions developed for popular languages.
|
Java |
|
|
C++ |
|
|
C# |
http://www.csharpfriends.com/articles/getarticle.aspx?articleid=336 |
|
PHP |
Meaningful name
We use
names everywhere in our code; we name our variables, functions, arguments,
classes, packages and modules. Names are the most common thing in
a program, so using meaningful names helps a lot to improve the quality,
readability and maintainability of our code. Following are some
points that you should consider when naming programming
elements.
Names of variables,
methods, classes should be able to answer following questions; Why
it exists? What it does? and How it is used? If you can answer those three
questions just by looking at the name, then we can consider it is a good name.
Yes, finding good name takes bit more time, but it is worthwhile. If your names
require commenting it is not a good name.
int m;
//number of messages to send
Variable name m doesn’t reveal anything, that’s why we needed those comments. What you should do is not commenting, rather you should use a meaningful name like ‘noOfMsgsToSend’, which clearly reveal our intention. Using meaningful names also increases the readability of your code as well. Consider following two code fragments and see the difference.
public boolean excecute(Message m)
{
for (int i = 0; i < 10;
i++) {
if (m.doit())
{
return
true;
}
}
return
false;
}
public boolean send(Message
message) {
for (int tryCount = 0;
tryCount < MAX_TRY_LIMIT; tryCount++)
{
if (message.send())
{
return
true;
}
}
return
false;
}
Avoid administration
We should avoid
leaving false clues which harm the meaning of the program. Avoid words whose
intended meanings vary from our intended meaning. Do not name group of items
such as an invoice as invoiceList unless it is actually a List, use some other
name like invoiceGroup or invoices.
Another important
thing is that, do not use names that sound and spell similarly such as
messagesToReport and messagesToRespond. Since our IDEs provide content assist,
we may type first few letters and select one from the list provided by the IDE.
If there are lots of similarly named variables there is a chance of selecting
the wrong one. Also do not use lower case L or upper case O as variable names,
they can be confused with number zero(0) and
one(1).
Another
mistake we commonly do is using number series names like a1, a2, a3… This is
common when we name arguments in a method. Instead of using
public void
copy(char [] c1, char
[] c2)
use meaningful names like public void
copy(char
[] source, char [] destination).
Class Names and
Method Names
Classes and objects
should have noun or noun phrase names like Customer, BankAccout, or Expense.
Class name should not be a verb. Avoid words like Manager, Processor, Data, or
Info in the name of a class.
Method names should
have verb or verb phrase such as expenseProjector, credit or debit.
Another important
thing is to pick one word for a concept and sticking in to it throughout the
program. If you use synonyms throughout the program it can be misleading and
difficult to understand. For example it is confusing to have fetch, get and
retrieve in different classes.
Also
when selecting names, select names from your problem domain and make sure
everybody in your team uses single name per concept. To achieve this, what you
can do is to define a language which covers the domain you are working on. So
you can be sure that everyone is using the same name to represent one
concept.
“Try to leave the code little better
than you found it”
Development process
Yes I do like coding conventions, and they need to be automatically verified (checkstyle) when you check in your code via a Continuous Integration environment. Eg Hudson.
What about testing? We need unit tests to make sure our code is working as desired. Add Concordion into the picture to have a full feedback look of your requirements and functional tests.
I know for a fact that think kind of end to end automation together with an AGILE development process is the key to a successful software project.
Post new comment