如何提出更清晰的界面名称?

时间:2011-03-10 22:55:31

标签: c# .net interface naming

我在应用程序中看到它具有以下接口:

IHasContent
IHasValue
IHasMesh
IHasGeometry
IHasTransformation

他们不应该吗?:

IHaveContent
IHaveValue
...

或者:

IIncludeContent
IIncludeValue
...

就个人而言,我倾向于制造它们:

IContent
IValue
IMesh
IGeometry
ITransform

因为ISomething已经暗示它具有something

至于最后一个,我应该改为ITransformable吗?

我认为使用I + (Has/Have/Include/Exist, etc) + Name会使界面名称更加混乱。

关于如何提出更好的界面名称并不感到尴尬的任何想法都是重点,并且意义何在?

7 个答案:

答案 0 :(得分:30)

其中一些名称(内容,价值等)含糊不清,几乎无法描述项目的内容/行为。通常,名称应尽可能具体和独特--IScriptParameter可能比IValue更具描述性。随着项目的增长,拥有更多描述性名称将使您的类型更容易区分(如果您不小心,最终可能会使用IValue和INumber以及IAmount来处理“值”的变化!)

如果您的界面(例如IMesh)意味着“提供网格的属性”,则IMesh是一个非常好的名称 - 它描述了您可以将对象视为网格的事实。

如果您的界面用于应用动作(例如,将对象渲染为网格,或将变换应用于对象),则考虑使用动词/形容词而不是名词命名(例如IRenderable,ITransformable) - 这是.net中的常见模式(IEnumerable(动词/形容词)而不是ICollection(名词),例如)

对我而言,“IHasMesh”听起来更像是IMeshContainer - 即它是一个包含网格的对象,界面允许我“获取网格”。所以它不允许我在网格中进行操作或查询数据,而只是通过接口获取整个Mesh对象。

所以我会用:

  • 可转换如果对象可以通过界面转换
  • IT转换如果对象可以直接使用,就好像它是转换
  • IHasTransform / ITransformContainer / ITransformProvider 如果对象是容器,可以查询以提取Transform对象

答案 1 :(得分:12)

就个人而言,我喜欢IHas + Word,因为接口名称描述了实现它们的类的属性。 例如:

public class Lolcat : IHasCheezburger

当我读到时,我很容易理解lolcats中有芝士汉堡。

另一方面,

public class Lolcat : ICheezburger

让我想知道lolcats HAVE 芝士汉堡或 ARE 芝士汉堡(这是解释继承时使用的传统动词)。

答案 2 :(得分:8)

首先要理解的是,名字中的“I”并不是指代词“I”,而是遵循接口以大写字母“I”开头的命名标准。

从这个意义上讲,接口实际上被命名为“HasContent”,“HasValue”等,因此不要将其更改为“HaveContent”和“HaveValue”,因为这样做会很尴尬。

话虽如此,我无法确切地看到这些接口的用途。接口(根据定义)旨在强制实现它的所有类的条件,并且我不确定这些接口是强制执行的 - 所有类都有一个名为HasContent()的函数?

我认为您应该专注于具有is a关系的接口。当您声明一个实现接口IList的类时,您并不是暗示您的类具有列表,而是您的类列表。< / p>

例如,其中一个是IHasGeometry ......好吧,这让我能够检查它是否有几何,但我实际上只想处理是的数字em>几何图形,所以我会创建一个名为IGeometricFigure的接口,从而将其用于限制在几何图形上运行的任何东西。

我同意这些名字听起来很尴尬,但我认为更多是因为这些界面被用于尴尬的目的,而不是因为它们名称不正确。

答案 3 :(得分:4)

您的初始接口名称列表听起来完全正确。接口名称应描述合同。例如,这是我最近遇到过的一个我非常喜欢的界面:

public interface IDeterminesEmptyValue
{
    bool IsEmpty { get; }
}

完美!这个名字说明了一切。 “I”指的是它是一个接口,其余部分描述了合同将履行的内容。

如果接口被称为IEmptyValue,则意味着接口保证实现者是空值。它不是 - 它具有确定值是否为空的能力。

(可能)没有一个班级被称为DeterminesEmptyValue。但是可能有一千个类都能够确定不同类型的值是否为空,并且此接口允许以通用方式调用它们。

界面应清楚地描述实现它的类的特定特征。在IContent的情况下 - 实施者 HAVE 内容,或实施者内容吗?

答案 4 :(得分:4)

我喜欢认为ISomething意味着某事,就像扮演某事物的角色,而不是它“拥有”或“包含”某事。所以,IFather意味着'我扮演父亲的角色',或者我是父亲'。 IDispatcher表示“我扮演Dispatcher”或“我是Dispatcher”等等。

有些人喜欢命名界面来回答“我该怎么办?”的问题。 :IListenForEventsILogExceptionsLike in this post

答案 5 :(得分:3)

接口用于多种用途,具有不同的混乱命名约定。在担心名称之前,首先要决定如何分离功能可能是件好事。不幸的是,微软的集合有太少的不同界面,最大的缺点是IReadableList和IAppendable,这两个都可以由IList继承但支持逆变和协方差支持[所以可以将IList(Cat)传递给期望IReadableList的代码(动物) )或IAppendable(Of SiameseCat)]。另一方面,也可以将事情分解得太精细,以便任何有用的类都必须实现几十个接口。

在不知道应用程序和界面中使用了哪些类型的功能的情况下,很难判断它们是否具有良好的粒度级别。听起来它们太细分了,但我无法说出来。一旦功能被适当地分组,那么担心名称是有意义的。

答案 6 :(得分:1)

“我”不代表“我”。它只代表界面。

但是微软的own guidelines用于命名接口。

  

名称应仅因地区而异   字母I在接口名称上加前缀。