|
|
OO Coding Standards - C#, Java...
This document outlines Naming standards that are useful to developers who use C# or Java as their programming language of choice. This is a great read for those who want to hone up their coding skills.
There are three naming conventions that are prevalent in the OO World. These are Pascal Naming Convention, the Camel Case Notation and Upper Casing. While programmers around the world seem to arbitrarily prefer naming convention, we should make a clear distinction between when one is used over the others, depending on context.
(01) The PascalNamingConvention
|
|
In the Pascal Naming convention, the first letter of the first word,
and the first letter of every word being concatenated to make the
identifier. A good example is the Microsoft / Mono naming convention in
the .NET Framework for Namespaces, Interfaces and Classes. Example
Microsoft.Windows.OperatingSystem, or
Novell.Mono.EnterpriseFrameworkClass, etc.
|
(02) The camelCaseConvention
|
|
In the camelCase Convention, the first letter of the first word is
always lowercase, other than that, it is similar to the
PascalNamingConvention.
|
(03) The UPPERCASE Convention
|
|
Not a convention really, but a bad habit that programmers have,
especially those from the days of GW-BASIC and COBOL. This is
undoubtedly undesirable for anything but constant definitions and
enumerations.
|
(04) The lowercase Convention
|
|
Not mentioned earlier, the lowercase convention is also camelCase, but
with only one concatenatenated word. For example, exception and
myException are both perfectly valid camel case identifiers. DO NOT use
all lowercase identifiers where more than one word is being
concatenated to create the identifier. More importantly, do not use
lowercase identifiers where the use of camel case is not permitted.
|
(05) Where to use what convention?
|
This is where the Hungarian Naming Convention developed by a great
Hungarian developer called Charles Simonyi who led Microsoft's
development team in the afx days while the Microsoft Foundation Classes
library was implemented. MFC is still in use to this day, though
abstracted by layers like the .NET framework.
You will see where camelCase can be used, and where UPPERCASE can be
used. Everything else is PascalNamingConvention. This rule of thumb
will take you far (until we get to Hungarian that is).
camelCase convention Should be used only for local method variables,
private variables, event handlers and catch blocks.
MyMethod()
{
try
{
int nVariable;
Button objButton = new Button();
objButton.Click += myButtonClickHandler;
…
}
catch(Exception ex) // or catch(Exception objException)
{
throw new Exception(“[MyMethod()] “ +
ex.Message);
}
}
public class MyClass
{
private int _nCounter=0;
}
Note that private members in a class should always begin with an
underscore. This is extremely _important. This will make your accessors
and mutators (properties:get/set) easier to read.
UPPERCASE Convention Should only be used for constants and enumerated
values.
const int PI=3.14159;
enum MyPossibleStates
{
UNKNOWN=0,
SLEEPING=1,
RUNNING=2,
AWAKE=3
}
(or)
enum MyPossibleStates
{
UNKNOWN,
SLEEPING,
RUNNING,
AWAKE
}
NOTE: Uppercase can also be used for abbreviations within Pascal. For
example: System.Web.UI or System.IO.
The PascalNamingConvention is Used for NameSpaces, Classes, Method
Arguments, Method Declarations, class members, method names, etc.
Everywhere that camelCase or UPPERCASE cannot be used. Simple Rule of
thumb.
|
(06) Hungarian naming convention
|
The Hungarian naming convention pertains to all identifiers you will
use in your programming to enable tying the type of identifier to the
identifier’s name. These make your life very simple when adhered.
The prime benefit of this notation is that anyone who is looking at
your code and is familiar with that notation can now tell a lot about
the variable without going back to the definition or declaration of
that variable.
NOTE: The Use of underscores
undermines the purpose of camel case and should be strictly avoided
except at the beginning of a variable or identifier as shown below.
As mentioned before, always precede private
members of a class with an underscore.
Example:
private Variable _myOwnLittleVariable = null;
private int _nInteger = 0;
private long _lLong = 0L;
where Variable is a class.
For local variables, prefix
the type into the variable name.
Example:
String strTemp = String.Empty;
DateTime dtTemp = System.DateTime.Now;
Int32 nTemp = 0;
Int64 lTemp = 0L;
When you follow this standard, it will make it easier to read sections
of code where these variables are manipulated without going to the
actual declaration section.
Namespaces are the most
important part of a development team that is emphasizing on the use of
Class Libraries to achieve Modular, reusable code.
Namespaces should be organized into the following category:
CompanyName.AppDomain.FunctionalArea.Feature
Example:
Eafx.EnterpriseClasses.CommonFunctions.Encryption
Eafx.EnterpriseClasses.CommonFunctions.SecureFTP
(notice how FTP is an abbreviation and hence UPPERCASE is used)
Eafx.AutomotiveClasses.BaseEntities.Customer
The above namespace would implement all classes that relate to the
Customer entity, from the Customer class itself, to classes that relate
directy to the Customer class like CustomerDetails.
Note that it may always not be needed to break a namespace down to so
many levels, for example:
CompanyName.AppDomain.FunctionalArea
should suffice if you don’t foresee breaking it down further, but
the bet is on that you will need to one day, and it is better to
organize now than to reorganize later.
Class Names Should NOT Use the
C Prefix (Bad MFC Habit). Rather, should be descriptive of what the
class is desiged to do.
While the use of common nouns and adjectives is allowable, the use of a
Proper Noun indicates specialization and should never done to a Generic
Base Class. The very fact that you are writing a class called
GMCustomer or BMWCustomer indicates that you are implementing a
specialized object. One Offs are bad unless there is a Generic base
class which the application consumes. (Remember extensibility). Design
for the principle or concept, not the instance. There should be no
Specialization without a Generalization. Therefore, any specific class
that you develop should always have a generalized base class, even if
you dont see the need for it then.
Examples:
CustomerAddress
CustomerVehicleInsurance
VendorService
Vendor
Interfaces should always be
prefixed with an I. The rest of the Interface name can follow the same
standards as a class name. (Yes, we kept this from MFC)
Examples:
IUnwanted
ISerializable
ITransaction
IVendor
Parameters that will be passed
to methods as arguments should always be prefixed with a p. This will make parameters passed
to other methods easier to identify and hence make the call flow more
implicit.
Examples:
CustomerAddress pAddress = new CustomerAddress(pCity,pState,pZip);
Customer objCustomer = Customer.Search(pAddress);
Methods should use Verbs or
Verb Phrases (with common nouns).
Examples:
DeleteCustomer()
Search()
ProcessData()
ProduceInformation()
Properties should always use
Nouns or Noun Phrases (with adjectives).
Examples:
strScreenBackGroundColor
dtCustomerDateOfBirth
nCustomerAge
Common Type Prefixes
In all the above examples, you see that local variables and
members that are base type instances use camel case, but the first word
is usually an abbreviation used to indicate the type of the variable.
Here are some common notations
that you can use to prefix your local variables. While there are too
many classes that you will instantiate and use on a daily basis, to
include on this list, this list is suggestive to the convention that
you will use. Just ensure that you stick to a standard.
| Type |
Prefix |
Example |
sbyte
|
sb
|
sbGreen, sbRed, sbBlue
|
short
|
s
|
sAge, sHoursWorked
|
int
|
n
|
nCounter, nFleas
|
long
|
l
|
lCustomerId, lContentLength
|
byte
|
by
|
byPixel, byValue
|
ushort
|
us
|
usNumber
|
uint
|
un
|
unNumber
|
ulong
|
ui
|
ulNumber
|
float
|
f
|
fCashValue
|
double
|
d
|
dCashValue
|
bool
|
b
|
bIsEmployeeWorking
|
char
|
c
|
cStringCharacter
|
|
(07) Too Complicated
|
In a real life (programming) scenario, the Hungarian Naming convention, especially the part where you need to prefix each variable with the type becomes very cumbersome. Especially in a world of intellisense and other code-completion tools, it may be argued that Following naming conventions is overkill. The goal here is simplicity - Standardization. When you standardize and follow a fixed set of rules, it means that the work that you leave behind for another programmer to complete or extend, is simple to maintain and utilize. This alone can save companies over 90% of the software cost over time.
C#.NET Programmers: Utilize a utility like FxCop on your source files to ensure that your code is standardized. If manually following a naming standard is cumbersome, which it is, this will enable you to ensure that your code is compliant with the programming standards for the Microsoft Programming Platform. Other platforms may/may not have such tools available.
Remember, the world of programming is turning into a work smart, not hard world - always has been, but increasingly so in the last 10 years. Ask me if I will ever use the Afx AppWizard again.
|
|
|