Java中的接口命名[关闭]

本文翻译自: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中有两个选择:

  1. Class = User, Interface = UserInterface Class = User,Interface = UserInterface
  2. 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() ). 如果你计划拥有不同类型的用户NoviceUserExpertUser等 - 我希望看到一个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等 - 被命名为这样,而不是像IComparableIIterable


#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约定可能有几个原因。

  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. 因此,即使List是一个接口,String也是一个实际的类,一个方法可能会传递给它们 - 在视觉上区分接口是没有意义的。

  2. 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. 因此,使接口脱颖而出是没有意义的。

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

1. 模块命名、数据库表命名、域模型命名、各分层的类/方法命名、页面的命名; 模块命名: a. 包命名:com.project_name.module_name.action/service/dao/ws; service的实现都置于com.project_name.module_name.service.impl下; b. 接口命名遵守XxxxService,接口实现遵守XxxxServiceImpl; 2. 包的设计、页面的层次结构设计(jsp/css/js等文件的结构); 3. log、异常(声明式异常)的约定设计; 4. 链接、按钮、表单提交的统一方式;通用式Ajax调用与页面跳转统一模型; 5. 响应一个请求的分层结构约定,列举几个示例(常规调用、Ajax调用、WebService调用、提供WebService暴露、硬件设备接口调用); 6. 验证代码质量的约定,如JUnit、EMMA、FindBugs、CheckStyle、PMD的使用;Hudson持续集成需注意的; 7. 压力测试、防内存泄漏测试; 基础CSS:标签的各种状态的样式;表格单双行的样式; 开发一个Action请求的响应: 前置条件:该Action涉及的Entity及EntityName.hbm.xml已经准备好。 步骤: a. 前端页面触发Action的请求; 统一采用全路径请求,URL格式: 1> basePath/web/moduleName/*_ *.action {1}  EntityName,{2}  ActionMethodName 2> basePath/web/moduleName/gotoXxx.action (无需调用Service,直接跳转) 包括jQuery的Ajax方式和非Ajax方式; 包括表单提交; 参数设值的方式: 1> URL参数: basePath/web/moduleName/*_*.action?entity.propertyName=paramValue&paramName=paramValue 2> 或 另外,对于表单的提交,前后台都必须做数据校验,SWDF已提供了此能力,进行简单的配置即可,前台直接提供类似以下代码即可,点此查看前端校验详细规则说明。 前端校验示例; 后台数据校验,点此查看校验详细说明. b. 配置struts-moduleName.xml; 直接跳转示例; 调用Service示例; c. 开发对应的{EntityName}Action类; 该类必须继承com.hikvision.swdf.xx.BaseAction,该Action类有一个关键属性entity,即泛型Entity类的一个实体,该属性默认填充好了请求提交过来的entity对应参数(即entity.propertyName); d. 开发Service接口和Service接口实现,并在Action通过set方法注入该Service; 接口文件:UserService 接口实现:UserServiceImpl 注入Service e. 开发DAO,DAO继承com.hikvision.xxx.HibernateBaseDAO; 示例 f. 配置applicationContext-*.xml; 配置DAO bean、Service Bean、Action Bean及注入的配置; g. 测试; 备注: 1. Action建议统一遵守通配符的约定,basePath/web/moduleName/*_ *.action {1}  EntityName,{2}  ActionMethodName 2. 统一命名规则:接口类似UserService,接口实现类型UserServiceImpl;(IUserService和UserServiceImpl) 开发一个Action调用关联应用提供的WebService 前置条件:该WebService?WSDL可正常获取 步骤: a. 配置applicationContext-wsclient.xml; Spring管理第三方WebService实例bean Jaxws-client配置代码 b. 生成第三方WebService接口文件;(提供系统自动生成) 自动生成代码 c. 页面调用Action请求,Action注入WebService实例bean; Action对应方法直接调用第三方WebService的相关方法; d. 测试; 备注: 1. 步骤b,接口文件必须同包名同类名置于src目录下; 开发一个Action调用关联应用开放的HTTP请求 步骤: 1. 页面调用Action请求; 2. Action类相应方法使用封装好的HttpClient相关工具类,准备好HTTP请求的相关参数header参数和body参数并以xml的方式提交HTTP请求; 3. 解析该HTTP请求返回值(XML或JSON); 4. 响应结果; 5. 测试; 备注: 开发一个需要对第三方应用发布的WebService 步骤: a. 开发WebService接口,@WebService进行注解该接口; b. 开发WebService接口实现类,@WebService注解该实现类,并制定endpointInterface; c. 配置applicationContext-ws.xml d. 测试 备注: 开发一个需要对第三方应用发布的RESTful Service 步骤: a. 开发RS接口,提供如下Annotation; b. 开发RS接口实现,并提供如下Annotation; c. 配置applicationContext-rs.xml 备注: 所有Annotation的涵义解释如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值