I work on a Java web-app that uses Spring for dependency injection and JMock for mocking out these dependencies in our unit tests.
Currently our team is at a point were we have a few different opinions in terms of how to name certain interfaces that we use. We have no issue with naming the interfaces in our domain that have multiple implementations, that is simple. However, when it comes to interfaces for which we only have one implementation and intend on only having one implementation in the future, we have hit a snag.
The reason that we have such interfaces is purely for mocking, for example, we have services and repositories that we mock out in our unit tests and these services will be named "DocumentMappingService" or for repositories "EmployeeRepository". At the moment some of the guys just prefix the associated interface name with an "I", i.e. "IDocumentMappingService" and "IEmployeeRepository". Others name the interface as I have above and then append an "Impl" after the interface name for the implementing class.
The third "faction" feels that both of these options are poor. Looking at literature such as the well-known "Growing object-oriented software, guided by tests" would lead one to believe that both of the before-mentioned options are poor and that the interface name should clearly define the contract and the implementing classes name should clearly specify how that contract has been implemented. We have found this quite difficult to do in the case I have mentioned above though.
I was hoping that someone out there has had a similar issue before and has some suggestions ito which option is the best and why. Also, if you think that the "I" and "Impl" options are both poor, then please suggest a specific alternative convention.
There's no "one" correct answer here. Naming is quite subjective but what matters the most is that it should be consistent throughout the code base. I would just like to add (to @fge's answer) some more options for you:
Making the Interfaces more generic.
EmployeeRepository implements Repository
DocumentMappingService implements MappingService
Calling your single implementations "defaults".
DefaultEmployeeRepository implements EmployeeRepository
DefaultDocumentMappingService implements DocumentMappingService
Calling your base implementations (if, sometimes extended) as "support".
EmployeeRepositorySupport implements EmployeeRepository
DocumentMappingServiceSupport implements DocumentMappingService
I come across these naming conventions a lot when using the Spring Framework.
Edit : In response to user
nyxz
's comment about the
-Base
or
Base-
convention.
Like I said before, naming is subjective and there's nothing wrong with using the Base
nomenclature as such. But, personally, I don't prefer using it. Here's why:
If your implementations would mostly be used directly, then the code instantiating the classes leaves an impression of breaking the OOP hierarchy. That perhaps a specific derived class should have been instantiated.
If your implementations would mostly be extended from, then the word Base
becomes redundant in a way. You're extending from it so, of course, it's a base class. Duh!
The 2nd point mostly applies to peripheral classes in your project. Extension points that you provide when you're publishing a framework or library to be used and extended in other projects.
On the other hand, a good use case for using the Base
terminology would be for classes internal to your framework that factor common functionality out of other peripheral classes. Since, these classes aren't supposed to be instantiated directly, they are marked abstract
, which is in line with the 1st point.
Here's the Adapter
hierarchy from the Android framework as an example:
Interface hierarchy.
public interface Adapter
public interface ListAdapter extends Adapter
public interface SpinnerAdapter extends Adapter
The abstract
Base
class that factors out the common behaviour and interface implementations.
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter
Peripheral classes that are mostly instantiated but sometimes extended by an Android application.
public class SimpleAdapter extends BaseAdapter implements Filterable
public class ArrayAdapter<T> extends BaseAdapter implements Filterable
An answer to such a question can only reflect the tastes of the person who answers... So these are my tastes:
- I hate the initial
I
. It brings nothing of value to the picture. It reminds me of the Hungarian notation where float variables were to be suffixed with _f
or the like. No.
- The
Impl
suffix is good enough. But on the other hand, it sounds weird.
I'd suggest two alternate proposals for a given interface Foo
:
- create a single implementation but not with the
Impl
suffix; find a more "appealing" name. For instance, TheOnlyOneFoo
;
- create a factory with an appended
s
: Foos
. Then, a Foo
instance would be a Foos.newInstance(whatever, args)
.
I prefer the second solution, for two reasons:
- it can hide the fact that the real implementation has an ugly name;
- it can be extended easily when you realize one day that "no, after all, there is more than one implementation for that": just add another static factory method; and if the only existing method in existence sounds too generic, you can just mark it as
@Deprecated
.
It could even be used in a manner so that all Foo
implementations are package local, or even private to the factory. But stack traces would look worse...
No real solution there ;)
edit: as for mocking:
- I'd recommend mockito. Really. It is very easy to use, and very powerful.
- If those are "one-implementation classes" you are dealing with, maybe there is a better alternative in the JDK itself? What is it that you want to do exactly? The JDK has hidden treasures...
And as a final note... Have you considered the builder pattern?