October 3, 2012

CodeSense: Smart Naming Practices

What's in a name? If you're a developer, there's quite a lot in a name actually. The names you choose for your namespaces, classes, interfaces, methods, fields, parameters, etc.. communicate what your application is, what it does, and how it is organized. Thus, it is important (if not absolutely necessary) that you use your CodeSense when choosing names.

Namespaces

Namespaces define the organizational structure for your code, and help to uniquely identify the classes that belong to your library. Here are some CodeSense tips for namespaces:

If you're releasing your library to the public, then your namespaces should always be prefixed with your application's URI in reverse-order, for example: com.brian-driscoll.myapp. The reason for this is to prevent namespace collisions with other libraries. You can of course follow this practice even if you're not planning to release your library to the public, but it is not strictly necessary.

Namespaces should be meaningful within the domain of your library or application. Avoid using overly generic namespaces like Utils

Namespaces should create a meaningful hierarchy within your application. A rule of thumb is that if you find yourself creating similar namespaces within your application, you most likely can (and should) group those namespaces together into the same namespace. For example, if you have one namespace called Companies.Addresses and another called Customers.Addresses, you should create a single Addresses namespace instead.

Classes

Classes define the participants in your application's domain, and should be named in a logical way.

Class names should always be nouns.

Class names should be specific with respect to the object they define. If your class name is overly broad or vague, then you've likely created a monster (aka "God") object that needs to be broken down into several smaller classes.

For business entities, classes should be named according to the problem domain, e.g.: Company, Employee, Customer, etc. Avoid unnecessary clutter in business entity class names, such as EmployeeData or CustomerInfo

Classes in the solution domain should be named according to the solution domain, e.g.: DatabaseConnectionFactory, PageEventHandler, etc.

Classes should be placed into appropriate namespaces, and similar classes should be put together into the same namespace.

Interfaces

Interfaces describe functionality that any class can implement.

Interface names should always be adjectives. For example, you should use a name like Sortable rather than a name like IOrderedCollection to describe the functionality that must be implemented to sort a collection of items.

Interface names should be specific about the functionality that they describe. If your interface name is overly broad or vague, then chances are your interface describes too many different kinds of methods and should be broken up into several interfaces instead.

Like classes, interfaces should also be put into appropriate namespaces, and similar interfaces should be put together into the same namespace.

Methods

Methods describe what an instance of your class actually does.

Method names should always be verbs.

Method names should generally not give an indication of what their return type is or what parameter types it expects. There are exceptions to this, however, such as methods that convert from one type to another (Convert.ToString()). However, a method name like GetEmployeeIdAsString() should be shortened to GetEmployeeId(); the fact that the return type is String will make it obvious that we're getting a string back.

Unsurprisingly, method names should describe at a high level what the method actually does. So, if the method creates a customer record and sends a confirmation email, then it should probably be called CreateCustomerAndSendConfirmationEmail (I'll stop short of explaining why such a method is most likely poorly written...).

Method names should be consistent. For instance, if you use the term "Insert" across your business object class definitions for methods that create database records, then using the term "Add" or "Create" in another class for a method that creates database records will likely cause a bit of confusion about your API.

If you use a language that requires you to write your own accessor and mutator methods, then your accessor and mutator methods should be named getFoo() and setFoo(), respectively, where foo represents a field in your class.

Fields and Parameters

Fields and parameters represent the atomic data of your application's domain.

Field and parameter names should always be nouns.

Field and parameter names should not give an indication of type. In other words, STOP using names like strFirstName, strLastName, etc. Furthermore, field names should not be prefixed with anything, including underscores (_employeeId) or whatever else you might think of using.

Both field and parameter names should be meaningful with respect to the data that they represent. One- or two-letter names most likely aren't very descriptive and should be avoided.

Like method names, field and parameter names should also be consistent. If you use "id" for the identifier field across your business object class definitions, then using "ID" or "Identity" or "identifier" for an identifier field in another class will cause confusion. Similarly, if you have two methods that take a parameter representing a person's first name, then the parameter should have the same name in both methods.

Thanks for checking out this article on naming practices, which is part of a new series called CodeSense. CodeSense is about making code easier to read and write by developing common sense conventions that can be applied immediately in nearly any programming language. Please contact me at brian (at) brian-driscoll (dot) com if you have questions, comments, or requests for future CodeSense topics.
Post a Comment