Java Interfaces/Implementation naming convention [duplicate]
Asked Answered
G

9

417

How do you name different classes / interfaces you create? Sometimes I don't have implementation information to add to the implementation name - like interface FileHandler and class SqlFileHandler.

When this happens I usually name the interface in the "normal" name, like Truck and name the actual class TruckClass.

How do you name interfaces and classes in this regard?

Guv answered 11/5, 2010 at 22:12 Comment(2)
You don't call the interface ITruck, and the class Truck?Payson
bad conventions are bad regardless who comes up with them, I have read that the silly Impl suffix first showed up in IBM Developer Works articles.Paco
P
1105

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 Systems 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

Paco answered 11/5, 2010 at 22:17 Comment(11)
If you have an answer that disagrees with this answer, please post it. The comments have devolved into extended discussion, which is a bit out of their wheelhouse.Front
The last comment about the single implementation is wrong. An interface is still a good choice, maybe to split the work with coworker or even to create a dummy or fake implementation for your JUnit test.Buine
Correct! One more thing, since Abstract* types don't add new contract, they should be considered wrong, too. Having abstract classes is all about violating SRP.Uke
About DTO I disagree, Imagine "Pet" ( the entity ) and "PetDTO" ok it's inelegant but you can easily understand the code. If it's Pet and Pet just in different package, it's not lisible anymore. Also, your exemples are good for interface but it's not always that evident imagine UserService and DefaultUserService, I use this solution but is it really more understandable than IService and Service for a single implementation which is really common in c# https://mcmap.net/q/87309/-interface-naming-convention-closedBuine
"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." — except when testing with mocks.Pittman
I dont understand the hundreds of upvotes. It seems that most of people ignores or dont see the testability. I agree with @mikhailian, if you realize you have only one implementetion of that interface, and you remove that interface, you cant isolate another class that has your class as dependency. So you cant unit test anymore the other class, it becomes an integration test.Glaze
The reason against is Hexagonal architecture when you want implementaion (infrastructure) be in a separate module with limited dependencies. But as of packages and paths you would want to have both interface and its implementation be found at the same path point: com.example.domain.MyAggregate of domain module and com.example.domain.MyAggregateImpl of infrastructure module.Weight
I have to disagree with dropping the interface when there is a single implementation. One of the advantages of still keeping an interface is flexibility. You might not have multiple implementations today but may need a new implementation tomorrow in which case the code is already decoupled by using the interface. Also very important is testability. Interfaces enable you to easily mock.Segment
What if you have a John class that extends Human and implements Human. Can't have them both be Human. One needs to be called HumanInterface, no?Clemons
@Clemons That's not a very good example. If your design needs an interface that says Human along with a parent class (probably abstract) that says Human, to me it looks like you got something seriously wrong with your abstraction.Planarian
Not every type is going to be as simple as Truck vs CementTruck. There are so many we cannot identify based on the name whether its an interface or an implementation. Some languages add impl, in scala sources we have like suffix #17122273. I like C# way of prefixing with an "I". Helps you to quickly see all interfaces. Imaging starting on a new project with thousands of classes and trying to find the feature you are looking for.Slowworm
T
123

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.

Tourney answered 12/5, 2010 at 0:48 Comment(10)
Nothing about the concept of Inversion of Control or Dependency Injection requires Interfaces for single implemenations of classes, a few popular implementations of IoC Containers force you to do silly things with Interfaces for single implementations. Simply passing in objects to a constructor is the original "Dependency Injection". And as for mocks, use something like Mockito and just have it mock out based on the actual class.Paco
Right, and then when you have a bug in the actual class, you can't isolate the bug to the actual class. Since, after all, the class is "tested" by its use. But it's not. You can't achieve isolation by using actual code. When two tests fail - one for the class, and one with the class that uses the class, which is at fault? Isolating via interfaces makes only ONE test fail - the test for the actual class, not the test for the class that uses the interface that the class implements.Tourney
you don't understand what Mockito does with the "actual class"Paco
You don't understand how easily a shared mock implementation can be shared for test reuse, rather than a custom mock using a mocking framework for different tests, re-inventing the wheel via setup code each time. Custom mock implementations are much cleaner in the long run, and have the benefit of being able to be documented - unlike dynamically generated proxies. Furthermore, unless you mock out every method in your implementing class, there's no guarantee that the unit under test doesn't have a dependency on the actual implementation - it should be able to work regardless.Tourney
@Tourney I really like the "Default". That really tells what it is. The "Default" implementation of interface.Burgee
This is my main objection to the accepted answer. It's absolutely valid to declare an interface even if you currently only have one concretion. By not declaring an interface all consumers are declaring API contracts that will be obsolete as soon as you decide you want to add or migrate to a new implementation.Pertinacious
I concede... if your APIs are all internal and you can easily refactor to inject the interface later I would totally do that. For me the interface is technically cleaner, but at the expense of extra effort (for both writer and readers).Pertinacious
completely true. another usage of interface is decoupling. i cant believe someone tells you dont need interface if there is only one implementation for that :/Bernice
I disagree with the Answer. This is not a hard and fast rule. If you are working on a library and want to expose the API, then using a interface is a must even if there is one implementation. However, just pairing every class with an interface is more of an abuse of the idea. Refer InterfaceImplementationPair concept / discussion by Martn Fowler. Am not saying because the Martin Fowler is saying it, but becasue after lates 2010s it is very easy to extract interface if need be. wrt testing, frameworks like Mockito, etc, would make more sense.Pelite
About the naming in the case when you are forced, for whatever reason, to have interface and only one implementation: When I see impl. called Default(InterfaceName) I assume there is another impl. (which will be wrong assumption). If I see (InterfaceName)Impl I assume it's only one.Menashem
B
65

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.

Bought answered 11/5, 2010 at 22:27 Comment(12)
I've seen many systems with an interface and a single class to implement that interface, like IXxx and Xxx, or Xxx and XxxImpl. I don't see the point. If you only have one implementation, why bother breaking it into two types? All you gained was having to write all the declarations twice and keep them in sync.Forsberg
@Jay: That kind of thing is usually done by people who are very orthodox about unit testing everything in isolation and no knowledge about (or access to) mocking frameworks that allow mocking concrete classes.Bought
@Borgwardt: I was thinking that it was done by old C programmers who think that, just like in C they had to create a .h for every .c module, think that in Java they must create an interface for every class! :-)Forsberg
Changing a class to an interface breaks binary compatibility. If there is only one implementation of an interface but in the future you might have two implementations (and backwards compatibility is important) then it is sensible to still extract the contract into an interface type.Szeged
@Nathan: very few projects require binary backwards compatiblity - and those should have very clearly defined and separated public APIs.Bought
I'm creating a plugin system (similar to Eclipse) that removes the plugin writers from the actual source code of my framework. I can't find any work around to writing public interfaces for my (often singular) private classes. EG. The user wants to access a Notebook object, but I don't want them to see the innards, so I create a INotebook to give them the method signatures without revealing my code. Is this what you mean by separate public APIs?Elayne
@sdasdadas: partially, because it means you can decide which public methods of your Notebook class are part of the API and which aren't - and that is not a decision you should make lightly. Also, those interfaces should probably be in a different package.Bought
In the case where you want to extract an interface that at present has only a single implementation, I like to name the interface as simple as possible and then prefix the implementation class with "Default". So in @Elayne Notebook case, the interface would be Notebook and the implementation would be DefaultNotebook. I think this falls in line with the CoC concept, but allows rewriting (pun intended) the Notebook implementation if needed either in your framework or by an application dependent on your framework.Ahlers
@MartinWoolstenhulme That's a good point and I believe the Swing library follows that standard for most of their Models; for example, the DefaultTableModel.Elayne
In conclusion: DefaultNotebook or NotebookImpl for interfaces with a single implementation.Schell
There is a justification: Decoupling dependent implementations.Glaze
Easier said than doen, #17122273Slowworm
D
41

I tend to follow the pseudo-conventions established by Java Core/Sun, e.g. in the Collections classes:

  • List - interface for the "conceptual" object
  • ArrayList - concrete implementation of interface
  • LinkedList - concrete implementation of interface
  • AbstractList - abstract "partial" implementation to assist custom implementations

I used to do the same thing modeling my event classes after the AWT Event/Listener/Adapter paradigm.

Dianndianna answered 11/5, 2010 at 22:37 Comment(0)
L
29

The standard C# convention, which works well enough in Java too, is to prefix all interfaces with an I - so your file handler interface will be IFileHandler and your truck interface will be ITruck. It's consistent, and makes it easy to tell interfaces from classes.

Lang answered 11/5, 2010 at 22:15 Comment(10)
That's just a throwback from COM programming. Why would you want to tell an interface from a class?Pansophy
Helps it stand out when you're looking over class names and don't have an IDE that points it out for you. Interfaces are important and should be designed properly.Mort
I used to work with C# and now working with Java. I find the C# convention much more logical. This long thread shows you that there is a need for name convention for interfaces and implantations, so saying this is not needed is little bit condescending.Hennery
the definition of tells you what it is public interface Truck is pretty explicit.Paco
It's explicit if you're looking at the interface code itself. If you're searching through a whole bunch of classes for the one interface, or you're looking at someone else's code, it really helps to have the interfaces separately visible.Wrench
@JarrodRoberson: I tend to agree with JamEngulfer - when doing code reviews, you might not have the help of IDE highlighting. If there's a clear convention and single-word types (Truck) are interfaces and multi-word types (SimpleTruck) are classes, then it makes sense to have this convention.Nuzzle
@GalMorad - logical fallacy Appeal to Tradition/Appeal to Common PracticePaco
This whole Q/A topic is an appeal to common practice... literally what "convention" means :)Mayorga
This is just terrible. I fail my students who do this! If you need to prefix your interfaces with I you're just doing a very poor job at naming your classes/interfaces.Nobie
The holy war of C# convention and Java. Just look at the ecosystem you work in. How Spring is implemented? I see -Impl suffix concept or simple name of the interface and detailed name for implementaions. There is no I- prefix here. If you want to code in Java and see beautiful and readable code just use common convention of what are you using, that's itPandect
I
25

I like interface names that indicate what contract an interface describes, such as "Comparable" or "Serializable". Nouns like "Truck" don't really describe truck-ness -- what are the Abilities of a truck?

Regarding conventions: I have worked on projects where every interface starts with an "I"; while this is somewhat alien to Java conventions, it makes finding interfaces very easy. Apart from that, the "Impl" suffix is a reasonable default name.

Inductile answered 11/5, 2010 at 22:32 Comment(16)
If the pattern holds (Comparable, Serializable, ...), then it should be Truckable.Dianndianna
in a real world implementation Truck would probably extend a Vehicle interface that supplied some even more common behaviors and properties.Paco
@Robert Harvey, @Bert F: Nope, the question is, what do Trucks do? And do they do it in your particular code? E.g. they might be "Ridable".Whey
@Whey - it was a joke - I'm sure @Robert's comment was too.Dianndianna
@BertF I'm sure Mecki's comment was a joke as well. Anyway, it should be TruckloadAware.Fleur
The best answer in fact!Greenockite
I like this answer the best - an interface should specify a capability of some sort, and Truck doesn't really describe what the interface does. Sortable, Comparable, Disposable etc more specifically describe capability and since it's better to have many smaller interfaces this fits well into that usage patternDensity
Don't make too many assumptions about what an interface should or should not specify; it depends on the situation. All you can say is that an interface is a (partial) abstraction of the underlying implementation that is useful in some context. So Serializable, TruckloadAware and Truck can all be valid interface names depending on the problem at hand.Moulding
This makes no sense, then what is List do you propose it should have been Listable? That is ridiculous.Paco
An interface named Truck makes sense as the interface List from the API of Java.Airdrop
This is just the logical fallacy Appeal to Tradition/Appeal to Common PracticePaco
@JarrodRoberson - Well... there is Iterable right? I think the issue is that this -able approach only really works for interfaces with a single behaviour. More complex interfaces are really composite concepts, defining a set of related behaviours e.g. List combines Addable, Removable, Indexable, etc.Pertinacious
This answer, particularly the bit about "indicate what contract an interface describes" is extremely underrated. You can avoid all sorts of issues by implementing interfaces this way.Participate
In case anyone can't tell jokes from not, the point here is not to add able, the point is to use abstract adjectives. For example, ListLike can be used to describe things that behave like lists. You can also use things like SupportsArithmetic to describe things that support arithmetic methods, which could be a combination of SupportsAddition, SupportsSubtraction, SupportsDivision, SupportsMultiplication, SupportsExponentiation. Adding able onto everything simply isn't how English works.Oleomargarine
(cont.) Now you could argue that using SupportsX is as bad as using IX, but it's definitely a lot more descriptive and, due to the wording of it, should only be reserved for when you're at a very atomic level where this is very little functionality that the interface is supporting. Otherwise you would have more information that could probably be used, like NumberLike/Numeric or VectorLike (the linear algebra vector).Oleomargarine
So what do I name the interface for a service that gets a list of users? UserServiceable? Userable? UserRetrieverable?Ledge
S
12

Some people don't like this, and it's more of a .NET convention than Java, but you can name your interfaces with a capital I prefix, for example:

IProductRepository - interface
ProductRepository, SqlProductRepository, etc. - implementations

The people opposed to this naming convention might argue that you shouldn't care whether you're working with an interface or an object in your code, but I find it easier to read and understand on-the-fly.

I wouldn't name the implementation class with a "Class" suffix. That may lead to confusion, because you can actually work with "class" (i.e. Type) objects in your code, but in your case, you're not working with the class object, you're just working with a plain-old object.

Sheepfold answered 11/5, 2010 at 22:16 Comment(4)
We don't need Hungarian notation in JavaSterilant
there is nothing "easier to read and understand on-the-fly".... if you see in the code "truck.drive()" why would you care whether the type of truck is Truck or ITruck? What useful information do you derive from knowing that truck is an implementation of an interface? NOTHING. If there is a Truck type and you need to specialize it, then you go find out what Truck isNeckwear
@SteveKuo mField is more silly than ISomething.Clyve
This is just the logical fallacy Appeal to Tradition/Appeal to Common PracticePaco
W
1

I use both conventions:

If the interface is a specific instance of a a well known pattern (e.g. Service, DAO), then it may not need an "I" (e.g UserService, AuditService, UserDao) all work fine without the "I", because the post-fix determines the meta pattern.

But, if you have something one-off or two-off (usually for a callback pattern), then it helps to distinguish it from a class (e.g. IAsynchCallbackHandler, IUpdateListener, IComputeDrone). These are special purpose interfaces designed for internal use, occasionally the IInterface calls out attention to the fact that an operand is actually an interface, so at first glance it is immediately clear.

In other cases you can use the I to avoid colliding with other commonly known concrete classes (ISubject, IPrincipal vs Subject or Principal).

Weinberger answered 11/5, 2010 at 22:40 Comment(4)
not even consistently doing it poorly :-)Paco
those "Service" and "DAO" suffixes should be packages, then you don't need that useless suffix either.Paco
I don't really find package qualification clarifies anything in terms of readability (though technically it disambiguates). Consider hibernate's Session which collides with every other Session out there. Any code with both is a mess to think through and read.Weinberger
Using a package name "DAO" is just silly. It implies that the only thing in there are DAO classes, but in fact I probably want my domain objects in there as well. Why not put your Truck, PickupTruck and TruckDao inside your 'Truck' package? In fact if you interface that TruckDao, it means you can later pull Trucks via different means. Not sure why you'd concrete class it.Hickox
D
0

TruckClass sounds like it were a class of Truck, I think that recommended solution is to add Impl suffix. In my opinion the best solution is to contain within implementation name some information, what's going on in that particular implementation (like we have with List interface and implementations: ArrayList or LinkedList), but sometimes you have just one implementation and have to have interface due to remote usage (for example), then (as mentioned at the beginning) Impl is the solution.

Dehaven answered 11/5, 2010 at 22:18 Comment(12)
You beat me to it. But yes, the Impl suffix is a good alternative.Catachresis
I agree, having "Truck" as the interface and "TrunkImpl" as the class name seems like the most common way to do it in Java.Ranson
Classes don't need a suffix to show that they're implementations of an interface; that's what the implements keyword is for. If I had to see Impl after all of my class names, I think I would shoot myself.Payson
common doesn't mean the same thing as correct, Robert Harvey is 100% correct.Paco
@Robert Harvey Then what can I do if I have an interface with just one implementation and no specific information to include in its name?Guv
Well, I'm in the camp that says distinguish your interface names, not your class names. What if your Truck class implements the Vehicle interface? Then naming your class TruckImpl wouldn't make any sense. But you could name your interface VehicleInterface or IVehicle (or even, simply Vehicle, if that's your sensibility), and call your class Truck with no problems.Payson
@Robert Harvey if the interface would represent a generic vehicle and the truck is a "specialization" of a vehicle, that would be fine. But it's just happens to be an example from a software for a truck company. So it SHOULD say truck when using the interface. Otherwise it's just awkward.Guv
if you have one implementation and one interface you probably should not have an interface to begin with.Paco
This is just the logical fallacy Appeal to Tradition/Appeal to Common PracticePaco
@JarrodRoberson - Are you saying that the Truck interface is Classable? :DPertinacious
@RobertHarvey - You are worrying about shooting the wrong person. :-)Paco
@Paco But then when used as a dependency, it would break the dependency inversion principle Depend upon abstractions, not concretions..Glaze

© 2022 - 2024 — McMap. All rights reserved.