SUMO Software Corporation Software Coding Standard¶
Created: 10 Apr 2000 2:51 PM
Last Modified: 5/12/2011 1:32:00 PM
Created by:
Mark S. Lauter,
Michael P. Hollis,
Scott W. ErtzDocument Revision: 3.0.0 – Wiki Version
Author's Note: This document was originally written for a specific development team. We found what worked for us over a six-month period and put it on paper. It may not work for your team "as is." Feel free to modify it to fit your needs. Some of the project layout recommendations may seem "thin" because we put each developer through training. This document was only intended as a quick reference. The most important thing to remember when creating a programming standard is this –
everyone on the team must buy in to the standard 100% or you're wasting your time. Don't insist on forcing people to do things they don't want to do. Instead, concentrate on finding a happy medium where all developers can work together within a common development/coding environment.
For information about this document, please feel free to email one of the authors.
Table of Contents
IntroductionNaming StandardGeneral StandardRules of Thumb Introduction
- The purpose of this document is to set forth a set of rules and guidelines that insure software quality, streamlined team development and ease of maintenance. The authors developed these rules and during practical experience leading US and international software teams over many years. They have been adopted in some form or other by no fewer than six software companies in the US.
- Code Complete by Steve McConnell, ISBN 1-55615-484-4, is
recommended required reading for all developers.
- Code that does not conform to the Coding Standard will not be accepted by SUMO Software Corporation in official product builds.
- Rules are made to be broken. Conscious Coding Standard violations should be viewed as an explicit warning by the programmer that the code block in question has been specially written to overcome some difficulty that could not be overcome while adhering to the standard. Comments should be added to the code to indicate intentional violation of the standard. As of this publishing the authors has not encountered any problem which required a violation of this standard.
- Code samples are provided in VB.Net, but the concepts are relevant for C#, C++, Delphi, PHP, JavaScript, etc.
- Remember that if you don't look at code for three months you will forget enough of how things work that future you is essentially no longer the original programmer. You will kick yourself if you don't follow some disciplined standard and you will praise yourself if you do.
- Some good principles to follow: http://www.artima.com/weblogs/viewpost.jsp?thread=331531
Naming Standard¶
- Excessive Hungarian Notation is not acceptable. We recently saw a coding standard that defined 8 pages of 2 to 6 letter prefixes for objects. That's over 200 prefixes. Absurd! How can you remember all those prefixes? You can't.
- Hungarian notation is used to denote lexical scope or context, not type.
- UI elements are prefaced with lowercase
u.
Example UI element definitions:
<input type="text" value="user@website.com" id="uEmailAddress" />
- Local variables are prefaced with lowercase
l. The only exception to this rule is loop counters.
Example local variable definitions:
Dim lCounter as Integer = 0
Dim lImage as Bitmap = Nothing
For i As Integer = 1 To 100
- Class member variables are prefaced with lowercase
m.
Example field variable definition:
Private mName as String = String.Empty
- Arguments are prefaced with lowercase
a.
Example procedure definition:
Public Sub MyProcedure(aUserName as String)
- Units are named for the class they contain. For example, if you have a class called
Employee, the unit containing the class would be called Employee.vb.
- Projects, libraries and executables, are named for the functional group of classes that they contain. For example, our object to database serialization classes are contained within the
SUMO Data API package and are contained within the namespace SUMO.Serialization.
- To avoid naming conflicts with 3rd party libraries, project and namespace names are always prefaced with some abbreviation that represents the company or product, for example SUMO Software Corporation uses
Sumo for libraries and product name for specific products like TRV for the TaxReturnVerifications product.
- Do not use an obscure abbreviation for any variable name. For example, use
mDatabaseConnection instead of mCon. If you can't type fast enough that this is a problem then take a typing class or find another career that is less keyboard intensive.
- Constants are declared in
ALL_CAPS with underscores. Actually, data belong outside of the code, but if you must use constants, they belong in ALL CAPS. Probably if you have constants in your code you don't know what you're doing and need to read Code Complete.
- Never name a variable
Tmp or Temp.
- When declaring the object that will be returned by a Function, use lResult. There should be only one lResult for a Function; define it at the top, return it at the bottom. One way in, one way out.
General Standard¶
- Only include one class per unit. Unit is programmer speak for a file. The exception to this rule is a class within a class, but even this could be accomplished with partial classes in .Net. If your language or dev environment allows you to include the classes in separate files then do so.
- In C++ and Delphi, arguments are always passed with the const keyword. This prevents side effects, memcopy operations and increases performance when passing strings. There's no way to do this in VB.net.
- Use the built-in dev environment code formatter, with common options across the team, to format your code before checking it into the version control system.
- Follow the principle of symmetry and ownership. The class with the responsibility of creating an object has the responsibility of deleting the object. This is less important in modern systems with garbage collection, but it's still a good principle because it helps you understand relationships between classes.
- Whenever possible, use return values instead of raising exceptions to report success or failure. This increases execution speed. Use Boolean true for success and false to indicate failure. Never use integers as return values. Instead use enumerated types to indicate state beyond success or failure.
- When accessing a private field from within the parent class, if properties or access methods are available for reading and writing then use them because they might be performing important processing that won't occur if you access the variable directly.
- Variable declarations should be made as close as possible to the code that will use the variable.
Rules of Thumb
- Methods, procedures and functions should be limited to a single purpose. Besides making the code easier to read and comprehend, it makes choosing a method name easier.
- Methods, procedures and function bodies should be short, probably less than one screen height, and never contain more than one nested loop. If you follow RoT #1 this is easy.
- If a method, procedure or function has more than one nested loop, then it probably has more than one purpose. Reevaluate the procedure and consider breaking it into as many methods as there are loops.
- Optimize code only after getting it to work and after using a performance profiler to identify bottlenecks. Comment out original, working code with a comment noting that the code has been optimized. This helps maintain readability. It's better to have slow, readable code that works than to have fast, unreadable code that doesn't work. Remember, you can buy a computer that's twice as fast as the one you have for about 3,000USD. Why would we pay a developer 5,000USD to spend a week shaving milliseconds from a commonly used function when we can buy a better computer for less?
- Data belong outside of the code. The code should be written in such a way as to allow data to change without having to recompile. This seems like common sense, but the authors have found from experience that it isn't.
- Only comment the purpose of methods if the purpose seems unclear. Excessive commenting is typically not well maintained, even by the most disciplined programmers. The corollary to this rule is this: Reading comments to determine the functionality of a code block will often lead to misconceptions about how the code works or what it does. Trust the code, not the comments.
- Don't break encapsulation.
- Don't make use of side effects.
- Don't hide exceptions by throwing different exceptions or by "swallowing" them with empty except blocks. If you must throw your own exception then add the original exception as a child to your new exception.