Naming Interfaces and Concretes

Recently, I had a short, interesting discussion with a few Smartpath developers about conventions for naming interfaces.
Two conventions were evident in their source code. I’ve used both in the past :-)
  • Prefix interfaces with ‘I’
  • Name interface by role and suffix its concrete implementation with “Impl”.
Neither sit well with me. I prefer to name Interfaces by their role and concrete classes by their specific implementation of that role. This allows me to write code with clear intent and consider that the readers of my higher layers may not always be developers. I’d like to think business analysts could read the higher layers and understand the intent.
Consider the following points:
  • Code to an interface - that is, create and assign concrete types to their interface or public type (contributes to the flexibility and longevity of code base)
  • Always try to write readable code (I once heard and like the idea that you should always code as if you’re writing a letter to another developer or business analyst).
  • Hide the details or plumbing in lower layers.
With these points in mind, its nice to lay down code in a format very close to english sentences. This is particularly important in the higher layered code, like the application layer.

User Story: As an operator, I search for a clients contractual information using <some identifier> …

Implementation:
ContractRepository contractRepository = getContractRepository() ;
contractManager.loadsContractFrom(contractRepository, id);
or, if you’re more inclined toward using builders:
contractManager.uses(client).toLoadContractFrom(contractRepository);
Looking at the contract repository, we’re not interested in the concrete implementation. My currency in this transaction is the interface, which clearly indicates that I’m using a type of contract repository to load the information, without clouding the issue with lower level details like the specific type - local database, cached area or gateway to another system.
public ContractRepository getContractRepository()
{
return new TemplateGateWay(gatewayCredentials, gatewayAddress);
}
So it makes sense, from the readers perspective, to say ContractRepository, not IContractRepository.
Likewise, it makes sense to provide a specific name to the concrete type like HibernateContractRepository or ContractGateway, not HibernateContractRepositoryImpl or the like.
There are times when choice of name is not as clear. For instance, we often face a situation where we have extracted an interface from a concrete to satisfy TDD (suspecting that the area may be a spot for variation in the near future). This is usually a case where our concrete is the default implementation of the interface or type.
In these situations, I like to use Default<Type name>. i.e. DefaultContractRepository() (this is a poor choice as I would never associate default with this type of role). As new concrete implementations are added, I either rename the Default type to a specific name or use it as an instantiatible base of the other concrete types.
I’d like to add another parting view:
Code is read more than its written. As such, its important to make your code readable to the widest audience possible. This increases its life span, reduces its cost and instills trust in your fellow developers and wider business collegues.
I’m interested in anyones comments about this topic.

One Response

  1. Well said! Its very similar in the Architectural industry. There are draftsmen and then there are Architects. Architects do more than design fancy stuff - they project manage. Its a progression too - you can’t be effective at one without the other.

    Marrawah Man - July 10th, 2008 at 4:07 am

Leave a Reply

You must be logged in to post a comment.