Coding Standards
I will begin my first post with a topic that is arguably the most important to have before beginning any software project: coding standards.
It may sound mundane and trivial, but establishing and adhering to coding standards will create a basic understanding amongst all programmers participating in a project, and make the code base easier to manage and maintain. Every programmer has their preference for writing code a certain way. Some may be more zealous than others and without a standard that all of them can understand and adhere to, it provides an opportunity for programmers to inject their own conventions that may not be in accord with the other participating programmers. This can lead to a mix of different styles that can muddy code clarity.
I would like to think that the rules established in a coding standard serves a purpose or underpins some logic. It is not sufficient to say that code must be written a particular way because someone saw it written that way somewhere else. Personally, there are two important criteria to consider: code clarity and code compactness. They are, but not necessarily, two competing demands that require compromise when establishing standard. Given that, I would like to enumerate the standards I prefer and why I like them.
Let me begin by defining code clarity and code compactness, although they are probably self-explanatory. Code clarity means that the programmer is able to quickly follow the code in a fluid manner without a lot of mental gymnastics. Code compactness is being able to fit as much code onto one screen as possible so as to minimize the amount of scrolling necessary to view the code. So as you can quickly see, compact code is not conducive to code clarity and vice versa.
Brace placement
There are two camps on this:
(1) opening brace always on the same line:if (index == 5) {
statements;
} else {
statements;
}
(2) opening brace always on a new line.
if (index == 5)
{
statements;
}
else
{
statements;
}
Neither has an upper advantage on code clarity; both are equally clear. However, the former wins in code compactness, especially when you have an if condition with multiple else-if conditions.
Consider the following situation where the first line is particularly long:
if ((index > 0) && (index < 100) && ((index % 2) == 1) ||
(index > 0) && (index < 100) && ((index % 2) == 1)) {
statements;
}
It is not necessarily clear immediately that the body of the if statement starts on the third line. In this situation, camp 1 stumbles on code clarity, whereas camp 2 delineates the beginning of the if body with the lone open brace on a separate line.
if ((index > 0) && (index < 100) && ((index % 2) == 1) ||
(index > 0) && (index < 100) && ((index % 2) == 1))
{
statements;
}
My preference is to use a combination of both (compromise!). If the statement or declaration before the opening brace fits neatly onto one line, then I will place the opening brace on the same line. If it spans more than one line, then I will put the opening brace on a separate line.
public boolean startIgnition(Key combo, Pedal threshold)
throws OutOfGasException, InvalidKeyException
{
statements;
}
Also important: always use braces to demarcate compound statements in loops and if-else
statements, even if they are not necessary for single statements.
if (p > 0)
value = doSomethingA();
else
value = doSomethingB();
Using braces promotes code clarity and is a safer practice because inserting a statement to the body in the future will certainly require braces. If a developer forgets the enclosing braces, the compiler will not raise an error and the code will not behave as expected.
if (p > 0)
value = doSomethingA();
else
value = doSomethingB();
doSomethingC(value); //no compile error, bad behaviour
Variable Naming
I have seen a multitude of conventions used to name constants; local, instance and class variables. There are those who prefer to prefix instance variables with m_ (for member variable), class variables with s_ (for static variables in Java parlance), all-caps for constants and no prefix for local variables, so as to be able to distinguish immediately the scope of the variable.
public static final int MAX_COUNT = 100; // constant
public static String s_default = "One"; // class variable
private String m_option = "Silence"; // member variable
In terms of code clarity, prefixing variables has an advantage in that you can unambiguously know the scope of the variable, and makes it difficult to declare a variable of the same name and unintentionally mask another variable. For example, following the above convention would make it difficult to declare a local variable that would mask an instance variable because the m_ prefix would only be used for instance variables. On the other hand, prefixing variables is not code compact, but I do not think a serious argument can be made for this over two extra characters.
Personally, I do not like using prefixes to distinguish a variables scope. I am not opposed to it, but I would not push for it either. I find it cumbersome and does not add a noticeable benefit to code clarity. The risk mentioned earlier of variable masking should be minimal if programmers use meaningful variable names.
The important factor in variable naming is providing meaningful names. Making variable names verbose and
descriptive not only increases code clarity but also doubles as self-documentation. Programmers tend to
trade these factors for code compactness by abbreviating variable names, using acronyms, or simply using
single-character variables. Opting for code compactness to save a few extra characters is too big a sacrifice
when meaningful names can make code self-documenting. Since programmers generally don't document code
(which they should), self-documenting code is the next best thing. If you can read code and immediately
understand the nature and context of a variable just by reading its name, then you have killed two birds
with one stone: clarity and compactness, because self-documenting code does not require copious
comments to describe what the code is doing. Using acronyms for variable names should be limited to well
known acronyms, such as requestXml
. Naming a variable ucb
, instead of
userConfirmButton
, is meaningless because only the programmer who named that variable would
immediately know what ucb
is used for. Single-character variables should only be permitted for
one situation: loop counters, otherwise, the name provides no useful information.
Loop termination
Loops should terminate normally. Do not use the break
keyword in order to jump out of a loop.
The break
keyword should only be used for the switch
statement. If you are using
a break
inside a loop, re-evaluate the loop condition so that the break
is no longer
required or consider using a different loop construct (for
, while
,
do...while
). It is easier to understand a loop whose terminating conditions are defined in one
location. Using a break
within a loop adds additional terminating condition within the loop,
which is not easily identified without examining the body of the loop.
Example of using break within a loop:
int[] numbers = { ... }; // an array of numbers
// find first negative number in array
int firstNegative = 0;
for (int i=0; i<numbers.length; i++) {
if (numbers[i] < 0) {
firstNegative = numbers[i];
break;
}
}
A better alternative would be:
int[] numbers = { ... }; // an array of numbers
// find first negative number in array
int firstNegative = 0;
int i = 0;
while (firstNegative == 0 || i < numbers.length) {
firstNegative = numbers[i];
i++;
}
No Magic Numbers
Avoid using numerical constants in your code. Define a meaningful named-constant instead. This improves readability, and localizes changes to where the named-constant is defined.
Avoid:while (!connected && attempts < 3) {
connected = makeConnection();
attempts++;
}
Preferred:
while (!connected && attempts < MAX_ATTEMPTS) {
connected = makeConnection();
attempts++;
}
Code Clarity Above All Else
Writing code that is easy to understand always trumps making code that is compact.
If there are two ways of writing a piece of code, where one is short but difficult to understand and the other is longer but simpler to read, then choose the option that is simpler to read.
Code that is short but difficult to understand:public static String getTypeOfNumber(int n)
return (n == 0) ? "zero" :
((n > 0) ? "positive" : "negative");
}
Equivalent code that is longer, but easier to understand:
public static String getTypeOfNumber(int n) {
if (n == 0) {
return "zero";
} else if (n > 0) {
return "postive";
} else {
return "negative";
}
}
Establishing a coding standard should be a consensus effort between all developers involved in a project. Rules and conventions should have purpose and be justifiable, not simply forced upon others with the reason that it was done previously elsewhere. Once a standard is established for a project, it should be respected.