In-Depth
Why Coding Standards?
Organizations adopt coding standards to ensure the delivery of reliable applications. See how standards can help reduce time for reviews and correct violations automatically.
- By Nigel Cheshire
- February 1, 2005
It's a fact of life: different people like to write code using different styles. Show me code written by 10 developers, and I'll show you 10 coding styles. So why try to develop and enforce coding standards? Because they'll save you time and money, and make you look smarter in the bargain.
The primary reason for adopting a set of coding standards is to make it easier for developers to read and understand each other's code. Although peer review is still relatively rare, almost everyone has to maintain—or, at least, step through—code written by someone else. A lot of time can be wasted just trying to decipher code that is not easy to understand. It's amazing how just a few, small differences in style can make reading code much slower.
According to Sun Microsystems, 80 percent of the lifetime cost of a piece of software goes to maintenance, and hardly any software is maintained for its whole life by its original author. Whether you believe statistics or not, when you think about it, it's common sense. To quote Bruce Eckel: "Code is read much more than it is written."
This issue is becoming key for many organizations. People at all levels in a development organization are focused like never before on costs; just look at all the brouhaha over offshoring and outsourcing. However, to get an effective grip on development costs, you need to understand the development process, and that means an understanding of the total cost of building and maintaining your software systems.
By the way, I may as well mention here that there's no reason that the adoption of coding standards should increase costs. All those fancy, multiline comments at the top of files with beautifully lined-up columns of asterisks are (or at least should be) a thing of the past. Coding standards should take care of easy decisions for you, leaving you free to concentrate on the real work. Overfussy styles should be replaced with more efficient equivalents.
Preempt Bugs
A second reason for adopting coding standards is to preempt bugs. Everyone knows that the cost of fixing a bug rises exponentially over time. Finding and fixing bugs in the development phase—and preferably even before unit testing—can save hours of time and resources later.
Another area—outside of cost—that gets a lot of attention when it comes to software bugs is safety. Common examples that have been cited include space shuttle missions, radiation therapy, and airplane applications. If faulty software can be reduced by preempting bugs and thereby reduce safety issues, coding standards are their own reward.
In addition to saving time and money, preempting bugs has another less-obvious (and sometimes, less-tangible) benefit: reputation. The reputation of your work as a developer or as part of a team is called into play each time you release a new application. You owe it to your teammates to develop code that doesn't cause them to pull their hair out should they have to work with it. The reputation of the product your company puts out is on the line; even more so if your application is part of a consumer good. You owe it to your end users, your customers, and your shareholders to ensure your product or application is the best it can be.
Certain coding standards can make it less likely that bugs will be introduced into the code, and if those standards can be applied as the code is written, the savings will be huge. For example, one of the standards from Sun's own set states: "Braces are used around all statements, even single statements, when they are part of a control structure, such as an if-else or for statement. This makes it easier to add statements without accidentally introducing bugs due to forgetting to add braces."
Another common area for the adoption of a set of standards is on code commenting. A good set of coding standards sets out a common philosophy on this subject. At Enerjy Software, we believe in keeping code comments to a minimum. For those of us who learned software development more than a few years ago, this sounds like heresy. This new approach to commenting—"the code is the documentation"—stems from hard-won experience with trying to maintain heavily commented code in which the comments have fallen out of sync with the code.
Keep in mind that bad or out-of-date comments are worse than useless; they can cause others a great deal of wasted time and frustration. To quote Sun documentation: "When you feel compelled to add a comment, consider rewriting the code to make it clearer."
Javadoc is a great tool to adopt for those areas of your code that justify the maintenance overhead of being well documented, such as APIs. If javadoc is used, though, it should be used correctly and completely, and standards can and should be applied to its use.
Code-Analysis Tools
Many well-meaning people have adopted the idea of coding standards, only to have them fall into disuse. Given that they seem to be such a good idea, why would this happen?
The problem is that you have to be very self-disciplined to remember to apply all of the standards while you are writing code. You have to learn and memorize them all (Sun's coding standards are concise, but they still run to 20 pages), and then remember to apply them all the time. Applying them can be especially difficult for people who are not used to using standards, or worse, people who are used to a different set of standards. It's not surprising that many coding standards fall into disuse.
Code-analysis tools give developers an easy way to check their code against a set of standards as it is being written. This analysis is a significant step forward in promoting the adoption of standards, since it makes it easy for developers to police themselves.
There are a few code-analysis tools on the market, including at least two open source offerings: PMD and Checkstyle, as well as commercial offerings.
Working a little like a grammar checker in a word processor, these tools apply a preconfigured set of rules to the code and point out any violations of the coding rules. Moreover, for many of the rules—in particular, the more straightforward rules—some of the tools will even suggest and apply a fix for you. This feature is especially useful for working with a situation in which you have a violation that is repeated many times throughout your body of code.
The key to a successful implementation of a code-analysis tool lies in defining your rule set, which should be based on—and ideally should define—your own set of coding standards. Although some tools have a set of rules built in, you may need to add your own rules to encompass special standards that are not covered by the standard rule set.
Rather than crosschecking all the standard rules against your own coding standards (a tiresome task that is unlikely to be completed anytime soon), you can take a more pragmatic approach by running the tool against your existing code base with the standard rule set enabled. For each problem that the tool finds, either fix your code or, if it's your style, disable the rule. Once you have completed this exercise, you can browse through the list of rules (one day over lunch) and see whether any of the rules that you disabled should be turned on, or modified to fit your own standards. In this way, you do not have to spend many hours crosschecking rules against your standards; otherwise, you may get so bogged down in the detail that you will never get started.
A Good Rule Set
What makes a good rule set? A good set of coding standards breaks down into four areas: standards compliance, unused elements, common coding errors, and J2EE compliance. Examples of standards compliance include:
- Correct names: Package names should contain only lowercase letters because package names are mirrored in the directory structure of the source code. Since different operating systems treat case sensitivity differently, it's better to standardize on a common case treatment for package names.
- Correct use of javadoc: Javadoc should contain an @param tag for every method parameter to explain the purpose of the parameter and any restrictions on input values.
- Length of classes: A class or interface that defines too many methods can be difficult to understand.
Examples of unused elements include:
- Private fields and methods: Private fields and methods that are never used should be removed, as they cause confusion.
- Local variables: It is quite common when segments of code that use local variables are removed that the developer forgets to remove the initial declaration of the variable. To avoid confusion, it should be removed.
- Method parameters: Again, unused method parameters should be removed, since they cause confusion.
Examples of common coding errors include:
- Incorrect comparisons: In general, computers cannot store or perform floating-point computations with floating-point numbers with complete accuracy because of internal rounding errors. If a and b are arbitrary floating-point numbers, it is usually the case that a / b * b != a, which means that it is risky to attempt to compare floating-point values for exact equality (using the == operator). It is a better practice to ensure that numbers are sufficiently close.
- Unterminated cases in switch statements: It is a common mistake in Java to accidentally allow one case in a switch statement to fall through to the next. Ensure that every case ends with one break, return, throw, or continue. It is not necessary to apply this rule to the final case in a switch statement, though many developers like to do so in case additional cases are added to the statement at a later date.
- Missing braces in loop and if-else statements: If the then or else clause in an if expression consists of a single statement, Java does not require you to enclose the statement in braces. However, this practice is dangerous. If the clause needs to be expanded to multiple statements, it is easy for a maintenance programmer to forget to introduce the braces, which will create a bug.
- Local variables hiding fields: It is potentially confusing for a local variable to have the same name as a visible field. For example, it is easy to introduce a bug by forgetting to use "this." to clarify the reference to the field.
Having ejbCreate() and ejbPostCreate() method signatures that do not match provides an example of J2EE compliance. The J2EE specification mandates that these two methods must have the same number and types of arguments, and it's easy for a developer to let them get out of sync, especially if they're not right next to each other in the source code. You may not notice the problem until after you've deployed the entity bean into your application server and started it—which can be a rather time-consuming way to find a bug!
Keep It Simple
Coding standards are being adopted by more development organizations as a means of ensuring the delivery of reliable and sound applications. Estimates suggest that 80 percent of the total cost of a piece of software go to maintenance, and not enough effort is being directed at ensuring that the quality goes in during the development process.
With the advent of coding standards, companies are saving money and time on the front end, reducing potential safety risks and safeguarding their reputation both internally and externally. Equally, development teams can reduce their time in code reviews, correcting coding standards violations that could be detected—and in some cases corrected—automatically.
Adopting a simple set of coding standards, together with their enforcement, make up the key actions that can save your development team hours of time and much frustration. The easiest way to help developers adopt the standards is by using a tool that allows developers to programmatically define and share a common set of standards and apply them while they are writing code, no matter what development environment they choose. Once a common set of standards has been defined, it should be shared among a development group.
If you introduce and enforce coding standards, you'll have firsthand knowledge to answer the original question posed earlier: why coding standards? And I'd be eager to hear about your experience and get your feedback on this topic.