Java接口命名约定

bre*_*777 24 java interface naming-conventions

我在一个Java Web应用程序上工作,该应用程序使用Spring进行依赖注入,使用JMock在我们的单元测试中模拟这些依赖项.

目前我们的团队在某一点上,我们在如何命名我们使用的某些界面方面有一些不同的意见.我们在域中命名具有多个实现的接口没有问题,这很简单.但是,当涉及到我们只有一个实现并且打算将来只有一个实现的接口时,我们遇到了障碍.

我们有这样的接口的原因纯粹是为了模拟,例如,我们有我们在单元测试中模拟的服务和存储库,这些服务将被命名为"DocumentMappingService"或存储库"EmployeeRepository".目前,一些人只是在关联的接口名称前加上"I",即"IDocumentMappingService"和"IEmployeeRepository".其他人如上所述命名接口,然后在实现类的接口名称后添加"Impl".

第三个"派系"认为这两个选项都很差.查看众所周知的"以测试为导向的面向对象的软件"这样的文献会使人们相信前面提到的两个选项都很差,并且接口名称应该明确定义合同和实现类名称应明确说明合同是如何实施的.我们发现在上面提到的情况下这很难做到.

我希望那里的某个人之前有类似的问题并且有一些建议,哪个选项是最好的,为什么.此外,如果您认为"I"和"Impl"选项都很差,那么请建议一个特定的替代惯例.

Rav*_*yal 34

这里没有"一个"正确答案.命名是非常主观的,但最重要的是它应该在整个代码库中保持一致.我想为你添加更多选项(@ fge的答案):

在使用Spring Framework时,我经常遇到这些命名约定.


编辑:在回答用户nyxz有关的评论-BaseBase-约定.

就像我之前说过的那样,命名是主观的,使用Base命名法是没有错的.但是,就个人而言,我不喜欢使用它.原因如下:

  1. 如果您的实现主要是直接使用,那么实例化类的代码会留下打破OOP层次结构的印象.也许应该实例化一个特定的派生类.

  2. 如果你的实现主要是扩展,那么这个词Base在某种程度上会变得多余.你正在扩展它,当然,它是一个基类.咄!

第二点主要适用于外设类在你的项目.您在发布要在其他项目中使用和扩展的框架或库时提供的扩展点.

另一方面,使用Base术语的一个很好的用例是用于框架内部的类,这些类将其他外围类的常用功能考虑在内.因为,这些类不应该直接实例化,所以它们被标记abstract,这与第一点一致.

以下是AdapterAndroid框架的层次结构示例:

  • 接口层次结构

    public interface Adapter
    public interface ListAdapter extends Adapter
    public interface SpinnerAdapter extends Adapter
    
    Run Code Online (Sandbox Code Playgroud)
  • abstract Base某些因素与众不同的行为和接口实现类.

    public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter
    
    Run Code Online (Sandbox Code Playgroud)
  • 外围类主要实例化但有时由Android应用程序扩展.

    public class SimpleAdapter extends BaseAdapter implements Filterable
    public class ArrayAdapter<T> extends BaseAdapter implements Filterable
    
    Run Code Online (Sandbox Code Playgroud)


fge*_*fge 5

这个问题的答案只能反映回答者的口味......所以这些是我的口味:

  • 我讨厌最初的I.它没有给图片带来任何价值.它让我想起了匈牙利符号,其中浮点变量是后缀_f等等.没有.
  • Impl后缀是不够好.但另一方面,这听起来很奇怪.

我建议给定接口的两个备用提议Foo:

  • 创建单个实现但不带Impl后缀; 找到一个更"吸引人"的名字.例如,TheOnlyOneFoo;
  • 创建一个附加的工厂s:Foos.然后,一个Foo实例将是一个Foos.newInstance(whatever, args).

我更喜欢第二种解决方案,原因有两个:

  • 它可以隐藏真实实现具有丑陋名称的事实;
  • 当你意识到有一天"不,毕竟有不止一个实现"时,它可以很容易地扩展:只需添加另一个静态工厂方法; 如果现有的唯一现有方法听起来过于通用,您可以将其标记为@Deprecated.

它甚至可以以某种方式使用,以便所有Foo实现都是本地包,甚至是工厂私有.但堆栈痕迹看起来会更糟......

没有真正的解决方案;)

编辑:至于嘲笑:

  • 我推荐mockito.真.它非常易于使用,而且非常强大.
  • 如果那些是你正在处理的"一个实现类",那么JDK本身可能有更好的替代方案吗?你想要做的是什么?JDK隐藏着宝藏......

最后要说明的是......你是否考虑过建造者模式?