25

I saw in an application where it had interfaces such as:

IHasContent
IHasValue
IHasMesh
IHasGeometry
IHasTransformation

Should they not be?:

IHaveContent
IHaveValue
...

Or?:

IIncludeContent
IIncludeValue
...

Personally I am leaning towards just making them:

IContent
IValue
IMesh
IGeometry
ITransform

Because isn't ISomething already implies that it has that something?

As for the last one, should I make it ITransformable instead?

I think using I + (Has/Have/Include/Exist, etc) + Name makes the interface names more confusing.

Any ideas on how to come up with better interface names that doesn't feel awkward, is to the point, and gets the meaning across?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689

8 Answers8

38

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
Jason Williams
  • 56,972
  • 11
  • 108
  • 137
19

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).

tugudum
  • 387
  • 1
  • 4
  • 8
    I can't tell whether to laugh or agree...:) – riwalk Mar 10 '11 at 23:05
  • Thanks but Stargazer also said the `I` doesn't refer to pronoun `I`, but just a prefix. But I am not sure if that's universally accepted. – Joan Venge Mar 10 '11 at 23:07
  • 2
    @Joan Venge, I'm not saying that it is universally accepted, I am saying that it is a universally *known* naming standard (same as the ever-known but ever-hated hungarian notation). – riwalk Mar 10 '11 at 23:08
  • 4
    @Joan Yes is is. I don't think you could find a lot of interfaces in the System namespace where you could interpret `I` as the pronoun. `I` is short for "Interface" and it used to distinguish interfaces from regular classes (see http://msdn.microsoft.com/en-us/library/8bc1fexb(v=vs.71).aspx) – tugudum Mar 10 '11 at 23:09
10

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.

riwalk
  • 14,033
  • 6
  • 51
  • 68
  • "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" - I think it is somewhat pointless to speculate about or judge identifier choice without knowing the underlying domain model. – O. R. Mapper Jan 09 '17 at 12:05
  • 1
    @O.R.Mapper ... and that matters ... why? – riwalk Jan 10 '17 at 21:57
  • Well, as you don't know the underlying domain model, the fact that you are "not sure what these interfaces are enforcing" is irrelevant and does not imply the interfaces are badly named. – O. R. Mapper Jan 10 '17 at 22:19
  • 1
    @O.R.Mapper That's exactly what I freaking said. What else did you think I meant when I said, "I'm not sure what these interfaces are enforcing"? To me that's obvious that I'm saying that I don't know what the "underlying domain model" is. – riwalk Jan 11 '17 at 16:28
5

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?

Rex M
  • 142,167
  • 33
  • 283
  • 313
  • But wouldn't it be better if it was IEmptyValue? – Joan Venge Mar 10 '11 at 23:08
  • Because in one of the replies Carra says "The names should differ only by the letter I prefix on the interface name." so if this was a class nobody would call it `class DeterminesEmptyValue`, right? – Joan Venge Mar 10 '11 at 23:09
  • @Joan `IEmptyValue` 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. 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. – Rex M Mar 10 '11 at 23:09
  • What about IMaybeEmptyValue? :O – Joan Venge Mar 10 '11 at 23:11
  • 1
    @Joan that wouldn't be bad, but it's not quite as descriptive - it could be empty, but it doesn't tell us that the class also has the ability to tell us. – Rex M Mar 10 '11 at 23:14
  • 1
    In my opinion, the interface mentioned in this answer is a **role** interface, along the lines of the use of interfaces as mentioned by Udi Dahan in [Making Roles Explicit] (http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan). – beluchin Feb 14 '14 at 11:35
  • This answer is underrated IMO. – Hazel へいぜる Mar 11 '21 at 18:51
  • I usually call it IEmptyCheckable, precisely because it is not guaranteed to be empty and the responsibility of the interface is to ensure that it is possible to check if the implementer is empty or not. – Jesper Risager Nov 29 '22 at 16:42
4

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

onedaywhen
  • 55,269
  • 12
  • 100
  • 138
driushkin
  • 3,531
  • 1
  • 24
  • 25
3

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.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • Thanks supercat, that's an interesting idea. Do you think MS did this for performance reasons? Like if you have 5 interfaces instead of one, that would potentially slow down initialization, etc? – Joan Venge Mar 15 '11 at 22:37
1

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.

Carra
  • 17,808
  • 7
  • 62
  • 75
-1

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)
Max
  • 414
  • 1
  • 4
  • 12