如何起一个更清晰的接口名称?

发布于 2024-10-21 02:18:02 字数 1429 浏览 1 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

蘸点软妹酱 2024-10-28 02:18:02

其中一些名称(内容、值等)很模糊,对描述项目的内容/行为作用不大。一般来说,名称应尽可能具体和独特 - IScriptParameter 可能比 IValue 更具描述性。随着您的项目的发展,拥有更多描述性名称将使您的类型更容易区分(如果您不小心,您可能最终会使用 IValue 、 INumber 和 IAmount 来处理“值”的变化!)

如果您的接口(例如 IMesh)意思是“提供网格的属性”,那么 IMesh 是一个非常好的名称 - 它描述了这样一个事实:您可以将对象视为网格。

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

对我来说,“IHasMesh”听起来更像 IMeshContainer - 即它是一个包含网格的对象,并且该界面允许我“获取网格”。因此,它不允许我对网格内的数据进行操作或查询,而只是通过接口获取整个网格对象。

所以我会使用:

  • ITransformable 如果对象可以通过接口转换
  • ITransform 如果对象可以直接使用,就好像它是一个 Transform
  • IHasTransform/ITransformContainer/ITransformProvider 如果对象是一个可以查询以提取 Transform 对象的容器

Some of these names (Content, Value, etc) are vague, and do little to describe the content/behaviour of an item. In general, names should be as specific and distinct as possible - IScriptParameter might be more descriptive than IValue. As your project grows, having more descriptive names will make your types much easier to distinguish (if you're not careful you could end up with IValue and INumber and IAmount to handle variations of "values"!)

If your interface (e.g. IMesh) means "provides the properties of a mesh", then IMesh is a perfectly fine name - it describes the fact that you can treat the object as if it were a Mesh.

If your interface is used to apply an action (eg. to render the object as a mesh, or to apply a transform to the object), then consider using a verb/adjective rather than noun naming (e.g. IRenderable, ITransformable) - this is a common pattern in .net (IEnumerable (verb/adjective) rather than ICollection (noun), for example)

To me, "IHasMesh" sounds more like IMeshContainer - i.e. it is an object that contains a mesh, and the interface allows me to "get the mesh". So it would not allow me to act on or query data within the mesh, but simply fetch an entire Mesh object through the interface.

So I would use:

  • ITransformable if the object can be transformed via the interface
  • ITransform if the object can be used directly as if it is a Transform
  • IHasTransform/ITransformContainer/ITransformProvider if the object is a container that can be queried to extract a Transform object
北渚 2024-10-28 02:18:02

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

public class Lolcat : IHasCheezburger

当我读到这篇文章时,我很容易理解lolcats里面有芝士汉堡。

另一方面,

public class Lolcat : ICheezburger

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

Personally, I like IHas+Word because the interface name describes a property of the classes that implement them.
For example:

public class Lolcat : IHasCheezburger

When I read that I easily understand that lolcats have cheeseburgers in them.

On the other hand,

public class Lolcat : ICheezburger

Makes me wonder if lolcats HAVE cheeseburgers or ARE cheeseburgers (which is the traditional verb used when interpreting inheritance).

↘紸啶 2024-10-28 02:18:02

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

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

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

我认为您应该关注具有 is a 关系的接口。当您声明一个实现接口 IList 的类时,您并不意味着您的类一个列表,而是意味着您的类是一个列表。

例如,其中之一是 IHasGeometry...好吧,这使我能够检查它是否具有几何图形,但实际上我只想处理是 几何图形,因此我将创建一个名为 IGeometricFigure 的接口,从而将其使用限制为对几何图形进行操作的任何内容。

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

The first thing you have to understand is that the "I" in the first names does not refer to the pronoun "I," but rather follows the naming standard that interfaces begin with the capital letter "I."

In that sense, the interfaces are actually named "HasContent," "HasValue," etc, so don't change it to "HaveContent" and "HaveValue", as that would be just as awkward.

With that being said, I can't exactly see what these interfaces are being used for. An interface (by definition) is intended to force a condition on all classes that implement it, and I'm not sure what these interfaces are enforcing--that all classes have a function called HasContent()?

I think that you should instead focus on interfaces having an is a relationship. When you declare a class that implements the interface IList, you are not implying that your class has a list, but rather that your class is a list.

So for example, one of them is IHasGeometry...well, that gives me the ability to check if it has geometry, but I would realistically only want to deal with figures that are geometric figures, so I would create an interface named IGeometricFigure instead, thus restricting its use to anything that operates on geometric figures.

I agree that the names sound awkward, but I think that is more because these interfaces are being used for an awkward purpose, not because they are improperly named.

网白 2024-10-28 02:18:02

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

public interface IDeterminesEmptyValue
{
    bool IsEmpty { get; }
}

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

如果该接口被称为 IEmptyValue,则意味着该接口保证实现者是一个空值。事实并非如此——它有能力来确定一个值是否为空。

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

接口应该清楚地描述实现它的类的特定特征。对于IContent - 实现者内容,还是实现者内容?

Your initial list of interface names sound exactly right. An interface name should describe the contract. For example, this is one interface I ran across recently that I quite liked:

public interface IDeterminesEmptyValue
{
    bool IsEmpty { get; }
}

Perfect! The name says it all. The "I" refers to the fact that it is an interface, and the rest describes what the contract will fulfill.

If the interface was called IEmptyValue, it would mean the interface is guaranteeing that the implementer IS an empty value. It's not - it has the ability to determine whether a value is empty.

(Probably) no class would be called DeterminesEmptyValue. But there could be a thousand classes which all have the ability to determine whether different kinds of values are empty, and this interface lets them all be called in a common way.

The interface should clearly describe a specific characteristic of the classes that implement it. In the case of IContent - do the implementers HAVE content, or the implementers ARE content?

野鹿林 2024-10-28 02:18:02

我喜欢认为 ISomething 意味着它某物,例如扮演某物的角色,而不是它“具有”或“包含”某物。因此,IFather 的意思是“我扮演父亲的角色”,或者“我是父亲”。 IDispatcher 表示“我扮演调度程序的角色”或“我是调度程序”等。

有些人喜欢命名接口来回答“我做什么?”的问题。 :IListenForEventsILogExceptions喜欢这篇文章

I like to think that ISomething means that it is Something, as in playing role of something, rather than that it 'has' or 'includes' Something. So, IFather means 'I play a role of father', or I am father'. IDispatcher means 'I play a role of Dispatcher' or 'I am Dispatcher', etc.

Some people like to name interfaces to answer a question 'what do I do?' : IListenForEvents, ILogExceptions. Like in this post

北城孤痞 2024-10-28 02:18:02

接口有多种用途,具有不同的混乱命名约定。在担心名称之前,最好先决定如何分离功能。遗憾的是,微软的集合具有太少的独特接口,最大的遗漏是 IReadableList 和 IAppendable,这两个集合都可以由 IList 继承,但支持逆变和协变支持 [因此可以将 IList(of Cat) 传递给需要 IReadableList(of Animal) 的代码) 或 IAppendable(Of SiameseCat)]。另一方面,也可能将事物分割得太细,因此任何有用的类都必须实现数十个接口。

如果不知道应用程序和界面中使用了哪些类型的功能,就很难判断它们的设计是否具有良好的粒度。听起来它们划分得太细了,但我真的无法分辨。一旦功能被适当分组,那么担心名称就有意义了。

Interfaces are used for many purposes, with different muddled naming conventions. Before worrying about names, it's probably good to first decide how to segregate functionality. Microsoft's collections unfortunately have too few distinct interfaces, the biggest ommissions being IReadableList and IAppendable, both of which could be inherited by IList but support contravariance and covariance support [so one could pass an IList(of Cat) to code expecting an IReadableList(of Animal) or an IAppendable(Of SiameseCat)]. On the other hand, it's also possible to split things too finely so any useful class has to implement dozens of interfaces.

Without knowing what types of functionality were used in the application and interfaces, it's hard to tell whether they were designed with a good level of granularity. It sounds like they're too finely divided, but I can't really tell. Once functionality is grouped suitably, then it makes sense to worry about the name.

神回复 2024-10-28 02:18:02

“我”并不代表“我”。它只是代表接口。

但 Microsoft 有其自己的指南命名接口。

名称应该仅因
接口名称上的字母 I 前缀。

The "I" doesn't stand for "me". It just stands for Interface.

But Microsoft has their own guidelines for naming interfaces.

The names should differ only by the
letter I prefix on the interface name.

素手挽清风 2024-10-28 02:18:02

.Net 库 中搜索不同的接口名称前缀,IWith 似乎是最好的选择。

考虑的选项:

可以通过以下代码验证结果:

const intervalID = setInterval(() => {
  const moreButton = document.querySelector(".more-button")
  if (moreButton && document.querySelector(".api-search-results tr:last-child td:first-child span").innerText.trim() == "Interface") {
    moreButton.click()
  } else {
    clearInterval(intervalID)
    console.log([...document.querySelectorAll(".api-search-results tr td:first-child span")].filter(el => el.innerText.trim() == "Interface").length)
  }
}, 100)

Searching for different interface name prefixes in the .Net library, IWith seems to be the best choice.

Options considered:

You can verify the result with the following code:

const intervalID = setInterval(() => {
  const moreButton = document.querySelector(".more-button")
  if (moreButton && document.querySelector(".api-search-results tr:last-child td:first-child span").innerText.trim() == "Interface") {
    moreButton.click()
  } else {
    clearInterval(intervalID)
    console.log([...document.querySelectorAll(".api-search-results tr td:first-child span")].filter(el => el.innerText.trim() == "Interface").length)
  }
}, 100)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文