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.
Interface names should be capitalized like class names. Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized. Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter.
There are two main naming conventions for interfaces in Java: no prefix or suffix for interfaces, ~Impl suffix for implementations, ~I prefix for interfaces.
Java uses CamelCase as a practice for writing names of methods, variables, classes, packages, and constants.
Constant Naming ConventionsJava constants should be all UPPERCASE where words are separated by underscore character (“_”). Make sure to use the final modifier with constant variables.
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.
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
. 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.Impl
suffix is good enough. But on the other hand, it sounds weird.I'd suggest two alternate proposals for a given interface Foo
:
Impl
suffix; find a more "appealing" name. For instance, TheOnlyOneFoo
;s
: Foos
. Then, a Foo
instance would be a Foos.newInstance(whatever, args)
.I prefer the second solution, for two reasons:
@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:
And as a final note... Have you considered the builder pattern?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With