本文翻译自:Interface naming in Java [closed]
Most OO languages prefix their interface names with a capital I, why does Java not do this? 大多数面向对象的语言都将其接口名称加上大写字母I,为什么Java不这样做呢? 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: 为了证明我的意思,如果我想要一个用户界面和一个用户实现,我在Java中有两个选择:
- Class = User, Interface = UserInterface Class = User,Interface = UserInterface
- Class = UserImpl, Interface = User Class = UserImpl,Interface = User
Where in most languages: 在大多数语言中:
Class = User, Interface = IUser 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. 现在,您可能会争辩说,您总是可以为用户实现选择一个最具描述性的名称,但问题就会消失,但Java正在推动POJO方法,而大多数IOC容器都广泛使用DynamicProxies。 These two things together mean that you'll have lots of interfaces with a single POJO implementation. 这两个因素共同意味着您将拥有许多具有单个POJO实现的接口。
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?" 所以,我想我的问题归结为: “是否值得遵循更广泛的接口命名约定,特别是考虑到Java框架似乎在哪里?”
#1楼
参考:https://stackoom.com/question/2GyW/Java中的接口命名-关闭
#2楼
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. 我倾向于不“实现”类似“用户”的东西,这就是为什么“IUser”通常不是以这里描述的方式所必需的。 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? 另外,如果你真的只打算制作一个用户并称之为用户,那么还有一个IUser界面的重点是什么? 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”可以省去选择实现的名称吗?
I think a more realistic example would be that some types of users need to be able to login to a particular API. 我认为一个更现实的例子是某些类型的用户需要能够登录到特定的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. 我们可以定义一个Login接口,然后有一个“User”父类,包含SuperUser,DefaultUser,AdminUser,AdministrativeContact等等,其中一些将根据需要实现或不实现Login(Loginable?)接口。
#3楼
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 preceding 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. 我个人不喜欢与接口前面I
,因为我不想被编码到界面,我认为这是在命名约定的条款更重要。 If you call the interface IUser
then every consumer of that class needs to know its an IUser
. 如果你调用IUser
接口,那么该类的每个消费者都需要知道它的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
. 如果你调用UserImpl
类,那么只有类和你的DI容器知道Impl
部分,而消费者只知道他们正在与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, eg 然后,我被迫使用Impl
因为一个更好的名字本身并不存在,因为实现根据实现被命名,因为这是重要的,例如
class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
#4楼
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. 根据我的经验,“I”约定适用于旨在为类提供契约的接口,特别是当接口本身不是类的抽象概念时。
For example, in your case, I'd only expect to see IUser
if the only user you ever intend to have is User
. 例如,在您的情况下,我只希望看到IUser
如果您打算拥有的唯一用户是User
。 If you plan to have different types of users - NoviceUser
, ExpertUser
, etc. - I would expect to see a User
interface (and, perhaps, an AbstractUser
class that implements some common functionality, like get/setName()
). 如果你计划拥有不同类型的用户NoviceUser
, ExpertUser
等 - 我希望看到一个User
界面(也许是一个实现一些常见功能的AbstractUser
类,比如get/setName()
)。
I would also expect interfaces that define capabilities - Comparable
, Iterable
, etc. - to be named like that, and not like IComparable
or IIterable
. 我还希望定义功能的接口 - Comparable
,可Iterable
等 - 被命名为这样,而不是像IComparable
或IIterable
。
#5楼
There is also another convention, used by many open source projects including Spring. 还有另一个约定,包括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. 我个人不喜欢“I”前缀,原因很简单,因为它是一个可选的约定。 So if I adopt this does IIOPConnection mean an interface for IOPConnection? 那么,如果我采用这个IIOPConnection意味着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. 如果该类没有“I”前缀,那么我知道它不是一个接口。这里的答案是否定的,因为并不总是遵循约定,并且监管它们将创建更多的约定本身保存的工作。
#6楼
There may be several reasons Java does not generally use the IUser convention. Java通常不会使用IUser约定可能有几个原因。
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. 因此,即使List是一个接口,String也是一个实际的类,一个方法可能会传递给它们 - 在视觉上区分接口是没有意义的。
In general, we will actually prefer the use of interfaces in client code (prefer List to ArrayList, for instance). 通常,我们实际上更喜欢在客户端代码中使用接口(例如,更喜欢List到ArrayList)。 So it doesn't make sense to make the interfaces stand out as exceptions. 因此,使接口脱颖而出是没有意义的。
The Java naming convention prefers longer names with actual meanings to Hungarian-style prefixes. Java命名约定更喜欢具有匈牙利式前缀的实际含义的较长名称。 So that code will be as readable as possible: a List represents a list, and a User represents a user - not an IUser. 因此代码将尽可能可读:List表示列表,User表示用户 - 而不是IUser。