你如何命名你创建的不同的类/接口? 有时我没有实现信息可以添加到实现名称中——比如接口FileHandler和类SqlFileHandler。

当这种情况发生时,我通常将接口命名为“正常”名称,如Truck,并将实际的类命名为TruckClass。

在这方面,如何命名接口和类?


当前回答

TruckClass听起来像是Truck的一个类,我认为推荐的解决方案是添加Impl后缀。在我看来,最好的解决方案是在实现名称中包含一些信息,在特定的实现中发生了什么(就像我们有List接口和实现:ArrayList或LinkedList),但有时你只有一个实现,并且由于远程使用(例如)必须有接口,那么(如开头提到的)Impl是解决方案。

其他回答

命名你的接口。卡车。不是卡车,因为它不是卡车,它是卡车。

Java中的接口是一种类型。然后你有DumpTruck, TransferTruck, WreckerTruck, CementTruck等实现了Truck。

当您使用接口代替子类时,只需将其转换为Truck即可。如List<Truck>。把I放在前面只是匈牙利风格的符号重复,它只会在代码中添加更多的东西。

所有现代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.

Impl后缀也是杂音。更多的同义反复。任何不是接口的东西都是实现,即使是部分实现的抽象类也是如此。你打算在每个类的每个名字上都加上那个愚蠢的Impl后缀吗?

接口是公共方法和属性必须支持的内容的契约,它也是类型信息。所有实现卡车的东西都是一种卡车类型。

看看Java标准库本身。你看到IList ArrayListImpl LinkedListImpl了吗?不,你看到的是列表和数组列表,还有LinkedList。这里有一篇关于这个问题的好文章。任何这些愚蠢的前缀/后缀命名约定都违反了DRY原则。

此外,如果您发现自己向对象添加了DTO、JDO、BEAN或其他愚蠢的重复后缀,那么它们可能属于一个包,而不是所有这些后缀。适当打包的名称空间是自文档化的,并减少了这些构思糟糕的专有命名方案中所有无用的冗余信息,大多数地方甚至在内部都没有以一致的方式坚持这些专有命名方案。

如果要使类名唯一,只能给它加上Impl的后缀,那么您需要重新考虑是否有接口。所以当你有一个接口和一个单独的实现,而不是唯一专门化的接口时,你可能在大多数情况下不需要接口。

然而,一般来说,对于可维护性、可测试性和模拟,提供接口是最佳实践。更多细节请看这个答案。

也可以参考Martin Fowler关于InterfaceImplementationPair这个主题的有趣文章

TruckClass听起来像是Truck的一个类,我认为推荐的解决方案是添加Impl后缀。在我看来,最好的解决方案是在实现名称中包含一些信息,在特定的实现中发生了什么(就像我们有List接口和实现:ArrayList或LinkedList),但有时你只有一个实现,并且由于远程使用(例如)必须有接口,那么(如开头提到的)Impl是解决方案。

我喜欢指示接口描述的契约的接口名称,例如“可比的”或“序列化的”。像“卡车”这样的名词并不能真正描述卡车——卡车的能力是什么?

关于惯例:我曾经工作过的项目中,每个界面都以“I”开头;虽然这与Java惯例有些不同,但它使查找接口变得非常容易。除此之外,“Impl”后缀是一个合理的默认名称。

有些人不喜欢这样,它更像是。net的约定而不是Java,但是你可以用大写的I前缀来命名你的接口,例如:

IProductRepository - interface
ProductRepository, SqlProductRepository, etc. - implementations

反对这种命名约定的人可能会争辩说,您不应该关心您在代码中使用的是接口还是对象,但我发现它更容易快速阅读和理解。

我不会用“class”后缀来命名实现类。这可能会导致混乱,因为您实际上可以在代码中使用“类”(即类型)对象,但在您的情况下,您不是在使用类对象,而是在使用普通的旧对象。

我使用这两种习惯:

如果接口是一个已知模式(例如Service, DAO)的特定实例,那么它可能不需要“I”(例如UserService, AuditService, UserDao),没有“I”都可以正常工作,因为后修正决定了元模式。

但是,如果你有一些一次性或两次的东西(通常是回调模式),那么它有助于将它与类区分开来(例如IAsynchCallbackHandler, IUpdateListener, IComputeDrone)。这些是为内部使用而设计的特殊用途的接口,有时IInterface会引起注意,操作数实际上是一个接口,因此乍一看就很清楚了。

在其他情况下,您可以使用I来避免与其他常见的具体类(issubject, IPrincipal vs Subject或Principal)发生冲突。