Java Interfaces/Implementation naming convention [duplicate]
Solution 1:
Name your Interface
what it is. Truck
. Not ITruck
because it isn't an ITruck
it is a Truck
.
An Interface
in Java is a Type. Then you have DumpTruck
, TransferTruck
, WreckerTruck
, CementTruck
, etc that implements Truck
.
When you are using the Interface
in place of a sub-class you just cast it to Truck
. As in List<Truck>
. Putting I
in front is just Hungarian style notation tautology that adds nothing but more stuff to type to your code.
All modern Java IDE's mark Interfaces and Implementations and what not without this silly notation. Don't call it TruckClass
that is tautology just as bad as the IInterface
tautology.
If it is an implementation it is a class. The only real exception to this rule, and there are always exceptions, could be something like AbstractTruck
. Since only the sub-classes will ever see this and you should never cast to an Abstract
class it does add some information that the class is abstract and to how it should be used. You could still come up with a better name than AbstractTruck
and use BaseTruck
or DefaultTruck
instead since the abstract
is in the definition. But since Abstract
classes should never be part of any public facing interface I believe it is an acceptable exception to the rule. Making the constructors protected
goes a long way to crossing this divide.
And the Impl
suffix is just more noise as well. More tautology. Anything that isn't an interface is an implementation, even abstract classes which are partial implementations. Are you going to put that silly Impl
suffix on every name of every Class?
The Interface
is a contract on what the public methods and properties have to support, it is also Type information as well. Everything that implements Truck
is a Type of Truck
.
Look to the Java standard library itself. Do you see IList
, ArrayListImpl
, LinkedListImpl
? No, you see List
and ArrayList
, and LinkedList
. Here is a nice article about this exact question. Any of these silly prefix/suffix naming conventions all violate the DRY principle as well.
Also, if you find yourself adding DTO
, JDO
, BEAN
or other silly repetitive suffixes to objects then they probably belong in a package instead of all those suffixes. Properly packaged namespaces are self documenting and reduce all the useless redundant information in these really poorly conceived proprietary naming schemes that most places don't even internally adhere to in a consistent manner.
If all you can come up with to make your Class
name unique is suffixing it with Impl
, then you need to rethink having an Interface
at all. So when you have a situation where you have an Interface
and a single Implementation
that is not uniquely specialized from the Interface
you probably don't need the Interface
in most cases.
However, in general for maintainability, testability, mocking, it's best practice to provide interfaces. See this answer for more details.
Also Refer this interesting article by Martin Fowler on this topic of InterfaceImplementationPair
Solution 2:
I've seen answers here that suggest that if you only have one implementation then you don't need an interface. This flies in the face of the Depencency Injection/Inversion of Control principle (don't call us, we'll call you!).
So yes, there are situations in which you wish to simplify your code and make it easily testable by relying on injected interface implementations (which may also be proxied - your code doesn't know!). Even if you only have two implementations - one a Mock for testing, and one that gets injected into the actual production code - this doesn't make having an interface superfluous. A well documented interface establishes a contract, which can also be maintained by a strict mock implementation for testing.
in fact, you can establish tests that have mocks implement the most strict interface contract (throwing exceptions for arguments that shouldn't be null, etc) and catch errors in testing, using a more efficient implementation in production code (not checking arguments that should not be null for being null since the mock threw exceptions in your tests and you know that the arguments aren't null due to fixing the code after these tests, for example).
Dependency Injection/IOC can be hard to grasp for a newcomer, but once you understand its potential you'll want to use it all over the place and you'll find yourself making interfaces all the time - even if there will only be one (actual production) implementation.
For this one implementation (you can infer, and you'd be correct, that I believe the mocks for testing should be called Mock(InterfaceName)), I prefer the name Default(InterfaceName). If a more specific implementation comes along, it can be named appropriately. This also avoids the Impl suffix that I particularly dislike (if it's not an abstract class, OF COURSE it is an "impl"!).
I also prefer "Base(InterfaceName)" as opposed to "Abstract(InterfaceName)" because there are some situations in which you want your base class to become instantiable later, but now you're stuck with the name "Abstract(InterfaceName)", and this forces you to rename the class, possibly causing a little minor confusion - but if it was always Base(InterfaceName), removing the abstract modifier doesn't change what the class was.
Solution 3:
The name of the interface should describe the abstract concept the interface represents. Any implementation class should have some sort of specific traits that can be used to give it a more specific name.
If there is only one implementation class and you can't think of anything that makes it specific (implied by wanting to name it -Impl
), then it looks like there is no justification to have an interface at all.