Java接口命名约定

时间:2013-06-24 12:20:43

标签: java interface naming-conventions

我使用的是一个Java Web应用程序,它使用Spring进行依赖注入,JMock用于在单元测试中模拟这些依赖项。

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

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

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

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

2 个答案:

答案 0 :(得分:33)

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

  • 使接口更通用。

    EmployeeRepository implements Repository
    DocumentMappingService implements MappingService
    
  • 调用您的单个实现“defaults”

    DefaultEmployeeRepository implements EmployeeRepository
    DefaultDocumentMappingService implements DocumentMappingService
    
  • 将您的基本实施(如果,有时会扩展)称为“support”

    EmployeeRepositorySupport implements EmployeeRepository
    DocumentMappingServiceSupport implements DocumentMappingService
    

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

<小时/> 修改: 回复用户nyxz-BaseBase-约定的评论。

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

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

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

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

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

    以下是Android框架中的Adapter层次结构示例:

    • 接口层次结构。

      public interface Adapter
      public interface ListAdapter extends Adapter
      public interface SpinnerAdapter extends Adapter
      
    • abstract Base类,它会影响常见行为和接口实现。

      public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter
      
    • 大多数实例化但有时由Android应用程序扩展的外围类。

      public class SimpleAdapter extends BaseAdapter implements Filterable
      public class ArrayAdapter<T> extends BaseAdapter implements Filterable
      

答案 1 :(得分:5)

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

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

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

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

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

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

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

那里没有真正的解决方案;)

编辑:至于嘲笑:

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

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