我在一个Java Web应用程序上工作,该应用程序使用Spring进行依赖注入,并使用JMock来模拟单元测试中的这些依赖。
目前,在如何命名所使用的某些接口方面,我们的团队还处于不同意见。命名域中具有多个实现的接口没有问题,这很简单。但是,当涉及到我们只有一个实现并且打算将来仅拥有一个实现的接口时,我们遇到了麻烦。
我们拥有此类接口的原因纯粹是为了模拟,例如,我们有在单元测试中模拟的服务和存储库,这些服务将被命名为“ DocumentMappingService”或存储库“ EmployeeRepository”。目前,有些人只是在关联的接口名称前面加上“ I”,即“ IDocumentMappingService”和“ IEmployeeRepository”。其他人按照上面的方法命名接口,然后在实现类的接口名称后附加“ Impl”。
第三个“派别”认为这两个选择都很差。查阅诸如著名的“在测试的指导下增长面向对象的软件”之类的文献,会使人们相信前面提到的两个选项都很差,并且接口名称应清楚地定义合同和实现类名称。应明确说明该合同的执行方式。但是,在我上面提到的情况下,我们发现很难做到这一点。
我希望那里的某个人以前也遇到过类似的问题,并提出了一些建议,即哪个选项是最佳选择以及为什么。另外,如果您认为“ I”和“ Impl”选项都不好,请提出一个特定的替代约定。
这里没有“一个”正确答案。命名是很主观的,但是最重要的是,它在整个代码库中都应该保持 一致 。我只想为您添加(作为@fge的答案)一些其他选项:
使接口更加通用。
EmployeeRepository implements Repository
DocumentMappingService implements MappingService
将单个实现称为 “默认值” 。
DefaultEmployeeRepository implements EmployeeRepository
DefaultDocumentMappingService implements DocumentMappingService
将基本实现(如果有时扩展)称为 “ support” 。
EmployeeRepositorySupport implements EmployeeRepository
DocumentMappingServiceSupport implements DocumentMappingService
使用 Spring Framework 时,我经常遇到这些命名约定。
编辑: 响应用户nyxz对-Base或Base-约定的评论。
nyxz
-Base
Base-
就像我之前说过的那样,命名是主观的,使用这样的Base命名法也没有错。但是,就我个人而言,我不喜欢使用它。原因如下:
Base
如果您的实现将大部分直接使用,那么实例化类的代码会给人留下破坏OOP层次结构的印象。可能应该实例化特定的派生类。
如果您的实现主要是从扩展而来的,那么这个词Base在某种程度上将变得多余。您正在扩展它,因此,它当然是基类。h!
在 第二 点主要适用于外设类在你的项目。在发布要在其他项目中使用和扩展的框架或库时提供的扩展点。
另一方面,使用该Base术语的一个好用例是框架内部的类,这些类将其他外围类之外的常用功能也包括在内。由于不应直接实例化这些类,因此将其标记abstract为与第 一个 点一致。
abstract
这是Adapter来自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 extends BaseAdapter implements Filterable