Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Interface Naming Conventions [closed]

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.

like image 807
brent777 Avatar asked Jun 24 '13 12:06

brent777


People also ask

What is the naming convention for interface in Java?

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.

Should interface name start with I in Java?

There are two main naming conventions for interfaces in Java: no prefix or suffix for interfaces, ~Impl suffix for implementations, ~I prefix for interfaces.

Which of the following are widely accepted naming conventions in Java?

Java uses CamelCase as a practice for writing names of methods, variables, classes, packages, and constants.

Should constants be capitalized Java?

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.


2 Answers

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:

  1. 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.

  2. 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 
like image 56
Ravi K Thapliyal Avatar answered Sep 30 '22 19:09

Ravi K Thapliyal


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?

like image 31
fge Avatar answered Sep 30 '22 19:09

fge