Java 接口/实现命名约定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2814805/
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
Java Interfaces/Implementation naming convention
提问by Amir Rachum
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
.
您如何命名您创建的不同类/接口?有时我没有要添加到实现名称的实现信息——比如 interfaceFileHandler
和 class SqlFileHandler
。
When this happens I usually name the interface in the "normal" name, like Truck
and name the actual class TruckClass
.
发生这种情况时,我通常以“正常”名称命名接口,例如Truck
并命名实际类TruckClass
。
How do you name interfaces and classes in this regard?
在这方面,您如何命名接口和类?
采纳答案by Andy White
Name your Interface
what it is. Truck
. Not ITruck
because it isn't an ITruck
it is a Truck
.
Interface
说出你的名字。Truck
. 不是ITruck
因为它不是一个ITruck
它是一个Truck
.
An Interface
in Java is a Type. Then you have DumpTruck
, TransferTruck
, WreckerTruck
, CementTruck
, etc that implement Truck
.
Interface
Java 中的An是Type。然后你有DumpTruck
,TransferTruck
,WreckerTruck
,CementTruck
,等那个implement 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 stylenotation tautologythat adds nothing but more stuff to type to your code.
当您使用Interface
代替子类时,您只需将其强制转换为Truck
. 如List<Truck>
. 放在I
前面只是匈牙利风格的符号重言式,它只为您的代码添加更多内容。
All modern Java IDE's mark Interfaces and Implementations and what not without this silly notation. Don't call it TruckClass
that is tautologyjust as bad as the IInterface
tautology.
所有现代 Java IDE 都标记了接口和实现,并且没有这种愚蠢的符号。不要把它TruckClass
认为是同义反复一样糟糕的IInterface
同义反复。
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.
如果它是一个实现,它就是一个类。这条规则唯一真正的例外,而且总是有例外,可能是类似AbstractTruck
. 由于只有子类会看到这一点,并且您永远不应该将其强制转换为Abstract
类,因此它确实添加了一些关于类是抽象的以及应该如何使用的信息。你仍然可以想出一个比AbstractTruck
and更好的名字,使用BaseTruck
orDefaultTruck
代替,因为abstract
在定义中。但由于Abstract
类永远不应该成为任何面向公众的接口的一部分,我相信这是规则的可接受的例外。制作构造函数protected
对跨越这个鸿沟大有帮助。
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?
而Impl
后缀只是更多的噪音。更多的同义反复。任何不是接口的东西都是一个实现,甚至是部分实现的抽象类。你打算Impl
在每个Class 的每个名字上加上那个愚蠢的后缀吗?
The Interface
is a contract on what the public methods and properties have to support, it is also Typeinformation as well. Everything that implements Truck
is a Typeof Truck
.
这Interface
是关于公共方法和属性必须支持什么的契约,它也是类型信息。一切都实现Truck
是一个类型的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 articleabout this exact question. Any of these silly prefix/suffix naming conventions all violate the DRYprinciple as well.
查看 Java 标准库本身。你看IList
,ArrayListImpl
,LinkedListImpl
?不,你看List
和ArrayList
, 和LinkedList
。这是一篇关于这个确切问题的好文章。任何这些愚蠢的前缀/后缀命名约定都违反了DRY原则。
Also, if you find yourself adding DTO
, JDO
, BEAN
or other silly repetitive suffixes to objects then they probably belong in a packageinstead 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.
另外,如果你发现自己在增加DTO
,JDO
,BEAN
或者其他愚蠢的重复后缀的对象,然后他们可能属于一个包,而不是所有的后缀。正确打包的命名空间是自我记录的,并减少了这些构思非常糟糕的专有命名方案中的所有无用冗余信息,大多数地方甚至内部都没有以一致的方式遵守这些命名方案。
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
.
如果你能想出的Class
唯一办法就是给它加上 后缀Impl
,那么你需要重新考虑是否有一个Interface
。因此,当您有一个Interface
和一个Implementation
不是唯一专门用于 的情况时,Interface
您可能不需要Interface
.
回答by tzaman
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.
标准的 C# 约定在 Java 中也能很好地工作,它是在所有接口前加上I
-前缀,因此您的文件处理程序接口将是IFileHandler
,卡车接口将是ITruck
. 它是一致的,并且可以很容易地从类中区分接口。
回答by Andy White
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:
有些人不喜欢这样,它更像是一种 .NET 约定而不是 Java,但是您可以使用大写的 I 前缀命名您的接口,例如:
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.
我不会用“Class”后缀命名实现类。这可能会导致混淆,因为您实际上可以在代码中使用“类”(即类型)对象,但在您的情况下,您不是在使用类对象,而是在使用普通对象.
回答by Mirek Pluta
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.
TruckClass
听起来像是一类Truck
,我认为推荐的解决方案是添加Impl
后缀。在我看来,最好的解决方案是在实现名称中包含一些信息,该特定实现中发生了什么(例如我们有List
接口和实现:ArrayList
或LinkedList
),但有时您只有一个实现并且由于远程使用而必须具有接口(例如),那么(如开头所述)Impl
就是解决方案。
回答by Michael Borgwardt
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.
如果只有一个实现类并且您想不出任何使其具体的东西(通过想要命名它来暗示-Impl
),那么看起来根本没有理由拥有一个接口。
回答by mfx
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?
我喜欢指示接口描述的契约的接口名称,例如“Comparable”或“Serializable”。像“卡车”这样的名词并不能真正描述卡车的特性——卡车的能力是什么?
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.
关于约定:我曾参与过每个界面都以“I”开头的项目;虽然这与 Java 约定有些不同,但它使查找接口变得非常容易。除此之外,“Impl”后缀是一个合理的默认名称。
回答by Bert F
I tend to follow the pseudo-conventions established by Java Core/Sun, e.g. in the Collections classes:
我倾向于遵循 Java Core/Sun 建立的伪约定,例如在 Collections 类中:
List
- interface for the "conceptual" objectArrayList
- concrete implementation of interfaceLinkedList
- concrete implementation of interfaceAbstractList
- abstract "partial" implementation to assist custom implementations
List
- “概念”对象的接口ArrayList
- 接口的具体实现LinkedList
- 接口的具体实现AbstractList
- 抽象“部分”实现以协助自定义实现
I used to do the same thing modeling my event classes after the AWT Event/Listener/Adapter paradigm.
我曾经在 AWT 事件/侦听器/适配器范例之后对我的事件类进行建模。
回答by Justin
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.
如果接口是一个众所周知的模式(例如 Service、DAO)的特定实例,那么它可能不需要“I”(例如 UserService、AuditService、UserDao),没有“I”就可以正常工作,因为 post-fix决定元模式。
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.
但是,如果您有一次性或两次关闭的东西(通常用于回调模式),那么有助于将其与类(例如 IAsynchCallbackHandler、IUpdateListener、IComputeDrone)区分开来。这些是专为内部使用而设计的专用接口,偶尔 IInterface 会提醒注意操作数实际上是一个接口这一事实,因此乍一看就很清楚了。
In other cases you can use the I to avoid colliding with other commonly known concrete classes (ISubject, IPrincipal vs Subject or Principal).
在其他情况下,您可以使用 I 来避免与其他众所周知的具体类(ISubject、IPrincipal 与 Subject 或 Principal)发生冲突。
回答by MetroidFan2002
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.
所以是的,在某些情况下,您希望通过依赖注入的接口实现来简化代码并使其易于测试(也可能被代理 - 您的代码不知道!)。即使您只有两种实现——一种是用于测试的 Mock,一种是注入到实际生产代码中——这并不会使接口变得多余。一个有据可查的接口建立了一个契约,它也可以通过一个严格的模拟实现来维护以进行测试。
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).
事实上,您可以建立测试,让模拟实现最严格的接口契约(为不应该为空的参数抛出异常等)并在测试中捕获错误,在生产代码中使用更有效的实现(不检查应该不为 null 因为模拟在您的测试中抛出异常,并且您知道参数不为 null 由于在这些测试后修复代码,例如)。
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.
依赖注入/IOC 对于新手来说可能很难掌握,但是一旦你了解了它的潜力,你就会想要到处使用它,你会发现自己一直在制作接口——即使只有一个(实际生产)实施。
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"!).
对于这个实现(您可以推断,并且您是正确的,我相信用于测试的模拟应该称为 Mock(InterfaceName)),我更喜欢名称 Default(InterfaceName)。如果出现更具体的实现,则可以对其进行适当的命名。这也避免了我特别不喜欢的 Impl 后缀(如果它不是抽象类,当然它是一个“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.
我也更喜欢“Base(InterfaceName)”而不是“Abstract(InterfaceName)”,因为在某些情况下,您希望基类以后可以实例化,但现在您坚持使用名称“Abstract(InterfaceName)” ,这会迫使您重命名类,这可能会引起一些轻微的混淆 - 但如果它始终是 Base(InterfaceName),则删除抽象修饰符不会改变类的名称。