Java中的接口命名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/541912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:00:46  来源:igfitidea点击:

Interface naming in Java

javainterfacenaming-conventions

提问by Allain Lalonde

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?

大多数面向对象语言的接口名称都以大写的 I 为前缀,为什么 Java 不这样做?不遵守该公约的理由是什么?

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 中有两个选择:

  1. Class = User, Interface = UserInterface
  2. Class = UserImpl, Interface = User
  1. 类 = 用户,接口 = 用户界面
  2. 类 = UserImpl,接口 = 用户

Where in most languages:

大多数语言的地方:

Class = User, Interface = IUser

类 = 用户,接口 = 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.

现在,您可能会争辩说,您总是可以为用户实现选择一个最具描述性的名称,问题就会迎刃而解,但是 Java 正在推动 POJO 方法,并且大多数 IOC 容器广泛使用 DynamicProxies。这两件事一起意味着您将拥有许多带有单个 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 框架的发展方向?”

采纳答案by starblue

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!

  • 前缀会降低可读性。

  • 在客户端中使用接口是标准的最佳编程方式,因此接口名称应尽可能简短且令人愉快。实现类应该更难看,以阻止它们的使用。

  • 当从抽象类更改为接口时,带有前缀 I 的编码约定意味着重命名该类的所有出现 --- 不好!

回答by tddmonkey

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 Ias I want to be coding to the interface and I consider thatto be more important in terms of the naming convention. If you call the interface IUserthen every consumer of that class needs to know its an IUser. If you call the class UserImplthen only the class and your DI container know about the Implpart and the consumers just know they're working with a User.

就我个人而言,我更喜欢不要在界面前面加上,I因为我想对界面进行编码,并且我认为在命名约定方面更为重要。如果您调用该接口,IUser则该类的每个使用者都需要知道它的IUser. 如果您调用该类,UserImpl则只有该类和您的 DI 容器知道该Impl部件,而消费者只知道他们正在使用User.

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

再说一次,我Impl因为没有更好的名字而被迫使用的次数很少,因为实现是根据实现命名的因为这很重要,例如

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO

回答by David Koelle

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 IUserif the only user you ever intend to have is User. If you plan to have different types of users - NoviceUser, ExpertUser, etc. - I would expect to see a Userinterface (and, perhaps, an AbstractUserclass that implements some common functionality, like get/setName()).

例如,在您的情况下,我只希望查看IUser您打算拥有的唯一用户是否是User. 如果您计划拥有不同类型的用户 - NoviceUserExpertUser等 - 我希望看到一个User界面(也许还有一个AbstractUser实现一些常见功能的类,例如get/setName())。

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

我还希望定义功能的接口 - ComparableIterable等 - 被命名为这样,而不是像IComparableIIterable

回答by ng.

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

我个人不喜欢“I”前缀,原因很简单,它是一个可选的约定。那么如果我采用这个,IIOPConnection 是否意味着 IOPConnection 的接口?如果该类没有“I”前缀,我是否知道它不是一个接口……这里的答案是否定的,因为并不总是遵循约定,对它们进行监管将创造更多的工作,而约定本身可以节省。

回答by Avi

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

Java 通常不使用 IUser 约定可能有几个原因。

  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.

  1. 面向对象方法的一部分是您不必知道客户端使用的是接口还是实现类。所以,即使 List 是一个接口而 String 是一个实际的类,一个方法可能会同时传递给它们——从视觉上区分接口是没有意义的。

  2. 通常,我们实际上更喜欢在客户端代码中使用接口(例如,更喜欢 List 而不是 ArrayList)。因此,让接口作为例外脱颖而出是没有意义的。

  3. Java 命名约定更喜欢具有实际含义的较长名称而不是匈牙利风格的前缀。这样代码将尽可能具有可读性:一个列表代表一个列表,一个用户代表一个用户——而不是一个 IUser。

回答by Andreas Petersson

Bob Lee said once in a presentation:

Bob Lee 曾在一次演讲中说:

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

如果您只有一个实现,那么接口的意义何在。

so, you start off with one implementation i.e. 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 instantiate User) will be unchanged and will not notice that suddenly they get passed an interface.

那么很明显:您的原始类被称为用户。您的界面现在称为 User。也许你有一个 UserProdImpl 和一个 UserTestImpl。如果你的应用程序设计得很好,每个类(除了实例化 User 的那些)都不会改变,并且不会注意到它们突然被传递了一个接口。

so it gets clear -> Interface User implementation UserImpl.

所以它变得清晰 - >界面用户实现UserImpl。

回答by Matt Briggs

In C# it is

在 C# 中是

public class AdminForumUser : UserBase, IUser

Java would say

Java会说

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.

正因为如此,我不认为约定在 java 中对于接口来说几乎没有那么重要,因为继承和接口实现之间存在明显的区别。我会说只要选择您喜欢的任何命名约定,只要您保持一致并使用某些东西向人们展示这些是接口。几年没做java了,但是所有的接口都在他们自己的目录中,这就是惯例。从来没有真正有任何问题。

回答by David Thornley

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?

这是真正意义上的更广泛的命名约定吗?我更多地在 C++ 方面,而不是真正关注 Java 和后代。有多少语言社区使用 I 约定?

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

如果您在此处有独立于语言的商店标准命名约定,请使用它。如果没有,请使用语言命名约定。

回答by KarstenF

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:

遵循良好的 OO 原则,您的代码应该(就实际/可能而言)依赖于抽象而不是具体的类。例如,通常最好编写这样的方法:

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.

如果您遵循这个想法,那么我认为,如果您给接口命名为“User”和“BankAccount”(例如),而不是“IUser”、“UserInterface”或其他变体,那么您的代码将更具可读性。

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.

如果你这样做,那么像“UserImpl”这样“丑陋”的具体类名应该安全地隐藏在代码的其余部分中,这些代码可以继续使用“漂亮”的接口名称。

回答by nairbv

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:

正如另一位发帖人所说,通常最好让接口定义功能而不是类型。我倾向于不“实现”像“用户”这样的东西,这就是为什么“IUser”通常在这里描述的方式并不是真正必要的。我经常将类视为名词,将接口视为形容词:

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?

另外,如果您真的只想创建一个 User 并将其称为 User,那么拥有 IUser 界面又有什么意义呢?如果您将有几种不同类型的用户需要实现一个通用接口,那么在接口上附加一个“I”可以节省您选择实现名称的时间吗?

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.

我认为一个更现实的例子是某些类型的用户需要能够登录到特定的 API。我们可以定义一个登录接口,然后有一个带有 SuperUser、DefaultUser、AdminUser、AdministrativeContact 等子类的“用户”父类,其中一些将或不会根据需要实现登录(可登录?)接口。