Wednesday, July 1, 2009

Naming Conventions

Here are simple rules to provide namespaces and names to the classes defined within an application. To illustrate these rules, let us consider a DataAccessLayer composed of a set of DataAccessor classes. We could therefore be working with the following classes:

A first DataAccessor managing Customers
A second DataAccessor managing Products
A third DataAccessor managing Orders

We here have a single concept, the DataAccessor, applied to multiple contexts, being the Customers, Products and Orders. As a rule, we should provide a namespace for each context, and our classes should be named with the context’s name, suffixed by the concept’s name.

This would lead to the following naming hierarchy:

DataAccessLayer
  Customer
    CustomerDataAccessor
  Product
    ProductDataAccessor
  Order
    OrderDataAccessor

Such a naming convention allows the addition of new contexts through new namespaces, and the addition of new concepts within the existing namespaces.

Let us suppose the DataAccessors are designed to work with DataRow classes, and suppose furthermore that our application now needs to manage Shipments. We could adjust our naming hierarchy as such:

DataAccessLayer
  Customer
    CustomerDataAccessor
    CustomerDataRow
  Product
    ProductDataAccessor
    ProductDataRow
  Order
    OrderDataAccessor
    OrderDataRow
  Shipment
    ShipmentDataAccessor
    ShipmentDataRow

Also, this naming convention prevents name clashes at different levels. First, the every namespace differ from all of the class names. That is, Customer differs from both CustomerDataAccessor and CustomerDataRow. Secondly, name clashes are also prevented in between layers.

Let us suppose a BusinessLogicLayer managing Customers through the concepts of Requests and Responses. We could then be facing this second naming hierarchy:

BusinessLogicLayer
  GetCustomer
    GetCustomerRequest
    GetCustomerResponse

Even though both layers work with the Customer context, name clashes would be prevented, as illustrated by the following code snippet:

getCustomerResponse.Name = customerDataRow.Name;
getCustomerResponse.Age = customerDataRow.Age;

Finally, this protection can be extended to nested classes with the following rule. Let us suppose the GetCustomerResponse class requires two nested classes, one for an Address, and another for a Customer. Since these classes are elements of the Response concept, their name should be suffixed with ResponseElement. This would lead the following naming hierarchy within the GetCustomerResponse class:

GetCustomerResponse
  AddressResponseElement
  CustomerResponseElement

Given this rule, name clashes are once again prevented as illustrated below:

customerResponseElement.Name = customerDataRow.Name;
customerResponseElement.Age = customerDataRow.Age;
getCustomerResponse.Customer = customerResponseElement;

No comments: