我使用的是一个Java Web应用程序,它使用Spring进行依赖注入,JMock用于在单元测试中模拟这些依赖项。
目前我们的团队在某一点上,我们在如何命名我们使用的某些界面方面有一些不同的意见。我们在域中命名具有多个实现的接口没有问题,这很简单。但是,当涉及到我们只有一个实现并且打算将来只有一个实现的接口时,我们遇到了障碍。
我们拥有此类接口的原因纯粹是为了模拟,例如,我们在单元测试中模拟了服务和存储库,这些服务将命名为“DocumentMappingService”或存储库为“EmployeeRepository”。目前,一些人只是在关联的接口名称前加上“I”,即“IDocumentMappingService”和“IEmployeeRepository”。其他人如上所述命名接口,然后在实现类的接口名称后添加“Impl”。
第三个“派系”认为这两个选项都很差。查看众所周知的“以测试为导向的面向对象的软件”这样的文献会使人们相信前面提到的两个选项都很差,并且接口名称应该明确定义合同和实现类名称应明确说明合同是如何实施的。我们发现在上面提到的情况下这很难做到。
我希望那里的某个人之前有过类似的问题并且有一些建议,哪个选项最好,为什么。此外,如果您认为“I”和“Impl”选项都很差,那么请建议一个特定的替代惯例。
答案 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
对-Base
或Base-
约定的评论。
就像我之前说过的那样,命名是主观的,使用Base
命名法并没有错。但是,就个人而言,我不喜欢使用它。原因如下:
如果您的实现主要是直接使用,那么实例化类的代码会留下打破OOP层次结构的印象。也许应该已经实例化了特定的派生类。
如果您的实施主要是扩展,那么单词Base
在某种程度上会变得多余。你正在扩展它,当然,它是一个基类。杜!
第二点主要适用于项目中的外围类。您在发布要在其他项目中使用和扩展的框架或库时提供的扩展点。
另一方面,使用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
; s
:Foos
的工厂。然后,Foo
实例将是Foos.newInstance(whatever, args)
。我更喜欢第二种解决方案,原因有两个:
@Deprecated
。甚至可以以某种方式使用它,以便所有Foo
实现都是本地包,甚至是工厂的私有。但堆栈痕迹看起来会更糟......
那里没有真正的解决方案;)
编辑:至于嘲笑:
最后说明......你是否考虑过建造者模式?