views:

4417

answers:

10

Most OO languages prefix their interface names with a capital I, why does Java not do this? What was the rationale for not following this convention?

To demonstrate what I mean, if I wanted to have a User interface and a User implementation I'd have two choices in Java:

  1. Class = User, Interface = UserInterface
  2. Class = UserImpl, Interface = User

Where in most languages:

Class = User, Interface = IUser

Now, you might argue that you could always pick a most descriptive name for the user implementation and the problem goes away, but Java's pushing a POJO approach to things and most IOC containers use DynamicProxies extensively. These two things together mean that you'll have lots of interfaces with a single POJO implementation.

So, I guess my question boils down to: "Is it worth following the broader Interface naming convention especially in light of where Java Frameworks seem to be heading?"

+17  A: 

Is there really a difference between:

class User implements IUser

and

class UserImpl implements User

if all we're talking about is naming conventions?

Personally I prefer NOT preceeding the interface with "I" as I want to be coding to the interface and I consider that to be more important in terms of the naming convention. If you call the interface IUser then every consumer of that class needs to know its an IUser. If you call the class UserImpl then only the class and your DI container know about the Impl part and the consumers just know they're working with a User.

Then again, the times I've been forced to use Impl because a better name doesn't present itself have been few and far between because the implementation gets named according to the implementation because that's where it's important, e.g.

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
MrWiggles
I think you'd want to know its a DAO since that describes the general functionality without needing to open the class. If I'm looking through the class files in a project its easy to see all the DAOs by looking for *DAO
Patrick
DAO is a well known pattern for database access, so having the pattern in the name makes it easy to know what the class does just by looking at its name.P.S. It would be better to follow the camel notation strictly ("AccountDao") such as in http://mina.apache.org/changes-between-2x-and-1x.html
Esko Luontola
@marker, it's not like having an I to indicate an interface. DAO tells you that the class or interface is an object for accessing account data, which is what the object does. Having an I tells you its an interface, which has nothing to do with the object itself but semantics of the language
MrWiggles
+1  A: 

In my experience, the "I" convention applies to interfaces that are intended to provide a contract to a class, particularly when the interface itself is not an abstract notion of the class.

For example, in your case, I'd only expect to see IUser if the only user you ever intend to have is User. If you plan to have different types of users - NoviceUser, SmartUser, etc. - I would expect to see a User interface (and, perhaps, an AbstractUser class that implements some common functionality, like get/setName()).

I would also expect interfaces that define capabilities - Comparable, Iterable, etc. - to be named like that, and not like IComparable or IIterable.

David
+10  A: 

There is also another convention, used by many open source projects including Spring.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

I personally do not like the "I" prefix for the simple reason that its an optional convention. So if I adopt this does IIOPConnection mean an interface for IOPConnection? What if the class does not have the "I" prefix, do I then know its not an interface..the answer here is no, because conventions are not always followed, and policing them will create more work that the convention itself saves.

ng
I like this, since it also helps get you in the mode of using interfaces for external dependancies rather then coupling the classes.
Matt Briggs
+14  A: 

There may be several reasons Java does not generally use the IUser convention.

  1. Part of the Object-Oriented approach is that you should not have to know whether the client is using an interface or an implementation class. So, even List is an interface and String is an actual class, a method might be passed both of them - it doesn't make sense to visually distinguish the interfaces.

  2. In general, we will actually prefer the use of interfaces in client code (prefer List to ArrayList, for instance). So it doesn't make sense to make the interfaces stand out as exceptions.

  3. The Java naming convention prefers longer names with actual meanings to Hungarian-style prefixes. So that code will be as readable as possible: a List represents a list, and a User represents a user - not an IUser.

Avi
+10  A: 

Bob Lee said once in a presentation:

whats the point of an interface if you have only one implementation.

so. you start off with one implementation - without an interface. later on you decide, well, there is a need for an interface here, so you convert your class to an interface.

then it becomes obvious: your original class was called User. your interface is now called User. maybe you have a UserProdImpl and a UserTestImpl. if you designed your application well, every class (except the ones that instanciate User) will be unchanged and will not notice that suddenly the get passed an interface.

so it gets clear -> Interface User implementation UserImpl.

Andreas Petersson
Using interfaces helps will Test Driven Development. We've run into numerous issues with out Domain Model and testing because we decided NOT to use interfaces. A friend of mine once quoted: "Everything is an interface, it will save you in the long run."
hooknc
if you use EasyMock, there is no real use for an extra interface.if you dont use something like EM, yes, than you will need an interface for every class that is need as a dependency in a class that needs to be tested. -> so you will have more than one impl (test+real)
Andreas Petersson
Mocking and easy proxy support. I'm sure there are other reasons to provide interfaces as well.
MetroidFan2002
As I recently said to a colleague, it costs nothing to introduce an interface now but can save you plenty of time later on.
MrWiggles
+27  A: 

I prefer not to use a prefix on interfaces:

  • The prefix hurts readability.

  • Using interfaces in clients is the standard best way to program, so interfaces names should be as short and pleasant as possible. Implementing classes should be uglier to discourage their use.

  • When changing from an abstract class to an interface a coding convention with prefix I implies renaming all the occurrences of the class --- not good!

starblue
Totally agree. One more key to type if you use autocompletion. Lots of files starting with an I.
Kalecser
Any decent IDE makes changing the code in the way you're describing easy. Also, When changing from an abstract class to an interface I'm pretty sure your clients will need to recompile anyway.
Allain Lalonde
agree with Allain
eglasius
+4  A: 

In C# it is

public class AdminForumUser : UserBase, IUser

Java would say

public class AdminForumUser extends User implements ForumUserInterface

Because of that, I don't think conventions are nearly as important in java for interfaces, since there is an explicit difference between inheritance and interface implementation. I would say just choose any naming convention you would like, as long as you are consistant and use something to show people that these are interfaces. Haven't done java in a few years, but all interfaces would just be in their own directory, and that was the convention. Never really had any issues with it.

Matt Briggs
A: 

Is this a broader naming convention in any real sense? I'm more on the C++ side, and not really up on Java and descendants. How many language communities use the I convention?

If you have a language-independent shop standard naming convention here, use it. If not, go with the language naming convention.

David Thornley
+2  A: 

Following good OO principles, your code should (as far as practical/possible) depend on abstractions rather than concrete classes. For example, it is generally better to write a method like this:

public void doSomething(Collection someStuff) {
    ...
}

than this:

public void doSomething(Vector someStuff) {
    ...
}

If you follow this idea, then I maintain that your code will be more readable if you give interfaces names like "User" and "BankAccount" (for example), rather than "IUser", "UserInterface", or other variations.

The only bits of code that should care about the actual concrete classes are the places where the concrete classes are constructed. Everything else should be written using the interfaces.

If you do this, then the "ugly" concrete class names like "UserImpl" should be safely hidden from the rest of the code, which can merrily go on using the "nice" interface names.

KarstenF
+1  A: 

As another poster said, it's typically preferable to have interfaces define capabilities not types. I would tend not to "implement" something like a "User," and this is why "IUser" often isn't really necessary in the way described here. I often see classes as nouns and interfaces as adjectives:

class Number implements Comparable{...}
class MyThread implements Runnable{...} class SessionData implements Serializable{....}

Sometimes an Adjective doesn't make sense, but I'd still generally be using interfaces to model behavior, actions, capabilities, properties, etc,... not types.

Also, If you were really only going to make one User and call it User then what's the point of also having an IUser interface? And if you are going to have a few different types of users that need to implement a common interface, what does appending an "I" to the interface save you in choosing names of the implementations?

I think a more realistic example would be that some types of users need to be able to login to a particular API. We could define a Login interface, and then have a "User" parent class with SuperUser, DefaultUser, AdminUser, AdministrativeContact, etc suclasses, some of which will or won't implement the Login (Loginable?) interface as necessary.

nairbv