当前位置:  开发笔记 > 编程语言 > 正文

Java中的接口命名

如何解决《Java中的接口命名》经验,为你挑选了9个好方法。

大多数面向对象的语言都将其接口名称加上大写字母I,为什么Java不这样做呢?不遵守这一惯例的理由是什么?

为了证明我的意思,如果我想要一个用户界面和一个用户实现,我在Java中有两个选择:

    Class = User,Interface = UserInterface

    Class = UserImpl,Interface = User

在大多数语言中:

Class = User,Interface = IUser

现在,您可能会争辩说,您总是可以为用户实现选择一个最具描述性的名称,但问题就会消失,但Java正在推动POJO方法,而大多数IOC容器都广泛使用DynamicProxies.这两个因素共同意味着您将拥有许多具有单个POJO实现的接口.

所以,我想我的问题归结为:"是否值得遵循更广泛的接口命名约定,特别是考虑到Java框架似乎在哪里?"



1> starblue..:

我不想在接口上使用前缀:

前缀会损害可读性.

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

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


任何体面的IDE都会以您描述的方式更改代码.此外,当从抽象类更改为接口时,我非常确定您的客户端无论如何都需要重新编译.
超级在这里,但是:如果IDE改变了一些简单的名称,那么_at all_并不重要.使用某种类型的实例的代码永远不应该关心该类型是接口还是类或什么.因此,在类型名称中暴露这样的细节是没有意义的,并且对理解有害.它暴露的类型和合同是最重要的!
"前缀伤害可读性"纯粹是主观的.和大多数命名约定一样.更重要的是,您的团队必须就如何做以使代码库保持一致达成一致.
完全同意.如果您使用自动完成,还需要输入一个键.很多以I开头的文件
此外,如果你要去IFoo的路线,不应该是CFoo的实现,当然失败的方法会抛出一个EFoo.
我个人喜欢使用`IInterface`和`OtherTypes`的C#方法(老实说,如果使用合适的sigil就可以了.)我发现这种一致性*有助于*对所有人的可读性.从类型转换为接口,反之亦然是Java和C#中的*源突破变化* - 这完全否定了"重命名事件"的要点.一个好的IDE,如ReSharper,可以帮助您通过源代码库安全,轻松地进行此更改.
@Allain Lalonde只有在您拥有接口和所有客户端的情况下才会出现这种情况,而事实并非如此.
"...接口的抽象类...前缀我暗示重命名所有类的出现" - 为什么这很糟糕?除了工具使得重命名某些东西变得微不足道,将某些东西从抽象类更改为接口是一个重大变化(如果没有别的,它是从"implements"到"extends"的变化).
来自http://wiki.eclipse.org/Naming_Conventions"对于接口名称,我们遵循"I"-for-interface约定:所有接口名称都以"I"为前缀.例如,"IWorkspace"或"IIndex"这个约定通过使界面名称更容易识别来帮助代码可读性."
Eclipse:"对于接口名称,我们遵循"I"-for-interface约定:所有接口名称都以"I"为前缀.例如,"IWorkspace"或"IIndex".此约定通过创建接口名称来帮助代码可读性更容易识别."

2> tddmonkey..:

两者之间真的有区别吗:

class User implements IUser

class UserImpl implements User

如果我们所说的只是命名惯例?

我个人不喜欢与接口前I,我想被编码到界面,我认为是在命名约定的条款更重要.如果你调用接口,IUser那么该类的每个消费者都需要知道它IUser.如果您打电话给班级,UserImpl那么只有班级和您的DI容器知道该Impl部件,消费者只知道他们正在使用User.

然后,我被迫使用的次数Impl因为一个更好的名字本身并不存在,因为实现根据实现被命名,因为这是重要的地方,例如

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO


DAO是众所周知的数据库访问模式,因此在名称中使用模式可以通过查看其名称来轻松了解类的功能.PS最好严格遵循骆驼符号("AccountDao"),如http://mina.apache.org/changes-between-2x-and-1x.html
@marker,它不像我指示一个界面.DAO告诉您,类或接口是用于访问帐户数据的对象,这是对象的作用.有一个我告诉你它的一个接口,它与对象本身无关,但与语言的语义无关
@Andrei:不,它是语义("DAO")与语言工件的不必要装饰("I"在接口中;事实,无论如何在代码中提到"接口IFoo ......")

3> Avi..:

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

    面向对象方法的一部分是您不必知道客户端是使用接口还是实现类.因此,即使List是一个接口,String也是一个实际的类,一个方法可能会传递给它们 - 在视觉上区分接口是没有意义的.

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

    Java命名约定更喜欢具有匈牙利式前缀的实际含义的较长名称.因此代码将尽可能可读:List表示列表,User表示用户 - 而不是IUser.



4> ng...:

还有另一个约定,包括Spring在内的许多开源项目都使用过.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

我个人不喜欢"I"前缀,原因很简单,因为它是一个可选的约定.那么,如果我采用这个IIOPConnection意味着IOPConnection的接口?如果该类没有"I"前缀,那么我知道它不是一个接口.这里的答案是否定的,因为并不总是遵循约定,并且监管它们将创建更多的约定本身保存的工作.



5> nairbv..:

正如另一张海报所说,通常最好让接口定义功能而不是类型.我倾向于不"实现"类似"用户"的东西,这就是为什么"IUser"通常不是以这里描述的方式所必需的.我经常把类看作名词和接口作为形容词:

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

有时形容词没有意义,但我通常仍然使用接口来模拟行为,动作,功能,属性等,而不是类型.

另外,如果你真的只打算制作一个用户并称之为用户,那么还有一个IUser界面的重点是什么?如果你想要有一些不同类型的用户需要实现一个通用接口,那么在接口上添加"I"可以省去选择实现的名称吗?

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



6> Andreas Pete..:

鲍勃李在演讲中说过一次:

如果您只有一个实现,那么接口的重点是什么.

所以,你从一个实现开始,即没有接口.稍后你决定,这里需要一个接口,所以你将你的类转换为一个接口.

然后它变得很明显:你的原始类叫做User.您的界面现在称为用户.也许你有UserProdImpl和UserTestImpl.如果你很好地设计了你的应用程序,那么每个类(实例化用户的那个)都将保持不变,并且不会注意到他们突然通过了一个接口.

所以它变得清晰 - >接口用户实现UserImpl.


使用接口有助于测试驱动开发.我们遇到了很多关于域模型和测试的问题,因为我们决定不使用接口.我的一位朋友曾引用过:"一切都是界面,从长远来看,它会拯救你."
模拟和简单的代理支持.我确信还有其他原因可以提供接口.
正如我最近对一位同事所说,现在引入一个界面并不需要花费任何费用,但可以节省你很多时间.
如果您可能在近中期的未来实现其他实现,那么接口将是一个优势.
我不喜欢“我将来可能需要另一个暗示”的说法。我更喜欢YAGNI的方法:不要为尚未发生的事情做计划。
现代的模拟框架不需要接口-它们可以模拟和监视具体对象

7> Matt Briggs..:

在C#中它是

public class AdminForumUser : UserBase, IUser

Java会说

public class AdminForumUser extends User implements ForumUserInterface

因此,我不认为约定在接口的java中几乎同样重要,因为继承和接口实现之间存在明显的区别.我只想选择你想要的任何命名约定,只要你是一致的并使用一些东西向人们展示这些是接口.几年没有完成java,但所有接口都只是在他们自己的目录中,这就是惯例.从来没有真正遇到任何问题.


也许我是糟糕的Java编码器,但我更喜欢C#风格,意味着所有接口都以'我'前缀开头:)
我不确定你和其他人在哪里得到这个假设的约定.它在Java库中并不明显......

8> David Koelle..:

根据我的经验,"I"约定适用于旨在为类提供契约的接口,特别是当接口本身不是类的抽象概念时.

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

我还希望定义功能的接口 - Comparable,Iterable等等 - 就像那样命名,而不是像IComparable或那样IIterable.


在某些客户端/服务器体系结构中,客户端需要知道接口而无需重量级服务器实现.

9> KarstenF..:

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

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

比这个:

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

如果您遵循这个想法,那么我认为如果您提供类似"User"和"BankAccount"(例如)的接口名称,而不是"IUser","UserInterface"或其他变体,您的代码将更具可读性.

应该关注实际具体类的唯一代码是构造具体类的地方.其他所有内容都应该使用接口编写.

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

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有