105

I have been reading "Clean Code" by Robert Martin to hopefully, become a better programmer. While none of it so far has been really ground breaking it has made me think differently about the way I design applications and write code.

There is one part of the book that I not only don't agree with, but doesn't make sense to me, specifically in regards to interface naming conventions. Here's the text, taken directly from the book. I have bolded the aspect of this I find confusing and would like clarification on.

I prefer to leave interfaces unadorned. The preceding I, so common in today’s legacy wads, is a distraction at best and too much information at worst. I don’t want my users knowing that I’m handing them an interface.

Perhaps it is because I'm only a student, or maybe because I have never done any professional or team based programming but I would want the user to know it is an interface. There's a big difference between implementing an interface and extending a class.

So, my question boils down to, "Why should we hide the fact that some part of the code is expecting an interface?"

Edit

In response to an answer:

If your type is an interface or a class is your business, not the business of someone using your code. So you shouldn't leak details of your code in this thrid party code.

Why should I not "leak" the details of whether a given type is an interface or a class to third-party code? Isn't it important to the third-party developer using my code to know whether they will be implementing an interface or extending a class? Are the differences simply not as important as I'm making them out to be in my mind?

6
  • 4
    I agree with your point. There is a point when too much information hiding is not very helpful. However, Even if you follow this guideline, you would still be able to tell the type using the IDE or an add-on.
    – NoChance
    Commented Nov 2, 2011 at 10:11
  • 4
    This question is essentially known as the question of "Hungarian notation", you should find plenty of arguments and the reason why most non-MS developers abandonded it under this keyword. Hungarian notation was mostly prevalent for variables, but it's essentially the same for types.
    – thiton
    Commented Nov 2, 2011 at 12:47
  • 2
    Prior title edit was a terrible one. This question is not about Hungarian notation in general simply because it mentions a convention that might be associated with it. The relative merits of HN are wholly irrelevant here; the question was specifically about interfaces vs. classes and whether or not the semantic differences are important/interesting enough to justify a special-case naming convention.
    – Aaronaught
    Commented Nov 2, 2011 at 23:52
  • Re to know whether they will be implementing an interface or extending a class: yes, but most users of your code will call it, not implement it or extend it, and they really couldn't care which it is.
    – david.pfx
    Commented Apr 8, 2014 at 11:17
  • For what it's worth, I massively prefer the "I" prefix. I also use an "Abstract" prefix on abstract classes for the same reason. It doesn't make a difference to consumers of the class/interface, but can make a big difference to those who need to provide instances of it, and also makes it much simpler for other developers who are reading your code. It means they can see at a glance what they're dealing with, instead of having to consult the IDE on a case by case basis for more information. I've just started using Angular and am finding it really annoying that they don't follow this convention!
    – Dan King
    Commented May 13, 2019 at 11:03

9 Answers 9

100

If you stop to think about it, you'll see that an interface really isn't semantically much different from an abstract class:

  • Both have methods and/or properties (behaviour);
  • Neither should have non-private fields (data);
  • Neither can be instantiated directly;
  • Deriving from one means implementing any abstract methods it has, unless the derived type is also abstract.

In fact, the most important distinctions between classes and interfaces are:

  • Interfaces cannot have private data;
  • Interface members cannot have access modifiers (all members are "public");
  • A class can implement multiple interfaces (as opposed to generally being able to inherit from only one base class).

Since the only particularly meaningful distinctions between classes and interfaces revolve around (a) private data and (b) type hierarchy - neither of which make the slightest bit of difference to a caller - it's generally not necessary to know if a type is an interface or a class. You certainly don't need the visual indication.

However, there are certain corner cases to be aware of. In particular, if you're using reflection, interception, dynamic proxies/mixins, bytecode weaving, code generation, or anything that involves messing directly with the environment's typing system or code itself - then it's very helpful and sometimes necessary to know right off the bat whether you're dealing with an interface or a class. You clearly don't want your code to mysteriously fail because you tried to add a class, rather than an interface, as a mixin.

For typical, vanilla, run-of-the-mill business logic code, though, the distinctions between abstract classes and interfaces do not need to be advertised because they'll never come into play.

All of this being said, I tend to prefix my C# interfaces with I anyway because that is the .NET convention used and advocated by Microsoft. And when I'm explaining coding conventions to a new developer, it's far less hassle to just use Microsoft's rules than to explain why we have our own "special" rules.

6
  • 42
    +1 for "All of this being said, I tend to prefix my C# interfaces with I anyway because that is the .NET convention used and advocated by Microsoft". This is reason enough for me in C#. By following this common standard it is more likely that other .NET programmers with identify the interface.
    – Robotsushi
    Commented Nov 4, 2011 at 17:00
  • 5
    As someone who writes both Java and C# the statement "All of this being said, I tend to prefix my C# interfaces with I anyway because that is the .NET convention used and advocated by Microsoft" cannot be understated - it's one of the things that helps me remember which language I'm working in,
    – Aidos
    Commented Sep 3, 2012 at 11:47
  • 5
    Another difference in .NET (but not in Java) is that many .NET languages do not allow interfaces to contain static methods, so hacking the I off an interface can give a good name for a class to hold static methods associated with the interface (e.g. Enumerable<T>.Empty or Comparer<T>.Default).
    – supercat
    Commented Jan 13, 2014 at 18:16
  • 4
    I have one concern. In C++ if you open a header and see that class Foo already extends class Bar, it is not immediately obvious if class Bar is being extended or implemented. So now you have to go and look in the class Bar header to decide whether it's okay to modify class Foo to extend class Baz. Furthermore, the I prefix gives an obvious visual clue if the "single base class" is being violated or not - so you get a sanity check every time you open up a header.
    – jsj
    Commented Jan 22, 2015 at 22:54
  • 2
    @jsj C++ has full MI, so the distinction is even more academic. Commented Nov 17, 2021 at 23:52
27

In many ways, consistency is more important than convention. As long as you're consistent in your naming schemes, they won't be hard to work with. Prefix interfaces with an I if you like, or just leave the name unadorned, it doesn't matter to me as long as you pick a style and stick with it!

3
  • 4
    +1 for consistency > convention. In C# you would prefix with an I and in Java you wouldn't. Different tasks call for different conventions
    – Bringer128
    Commented Nov 3, 2011 at 9:05
  • 5
    +1 while I'd personally prefer not to have Is on my interfaces, being inconsistent with the BCL and 3rd party libraries used in .Net projects is not an option imho.
    – jk.
    Commented Nov 3, 2011 at 10:35
  • If you ever use interfaces from the .net standard library or use third-party libraries or frameworks they will use the I-prefix for interfaces. So realistically you cant be consistent without using the convention of the platform.
    – JacquesB
    Commented Apr 20 at 10:37
14

Well this is not about implementing the interface or extending a class. In thoses cases, you know anyway what you are doing.

However, when third party code (another module of the application for exemple) manipulates you data, this code should not care if you are presenting an interface or a class.

This is the whole point of abstraction. You are presenting to this third party code an object of a given type. This given type has some member function you can call. That's enough.

If your type is an interface or a class is your business, not the business of someone using your code. So you shouldn't leak details of your code to this third party code.

By the way, interfaces and classes are reference types at the end. And this is what matters. So this is what your naming convention must emphasize.

0
13

The book is full of good stuff, but I would still add "I" to the interface name.

Imagine you have public interface ILog with a default implementation public class Log.

Now, if you decide to have public interface Log, all of a sudden you have to change Log class to public class LogDefault or something on those lines. You went from having one extra character to seven - surely that's wasteful.

There is often a fine line between theory and practice. In theory this is a really good idea, but in practice it's not so good.

9
  • This is also mentioned in the .NET documentation
    – levininja
    Commented Nov 6, 2014 at 16:11
  • 67
    "Imagine you have public interface ILog with a default implementation public class Log." - Then you have a poor name for your default implementation. What does Log do? Log to the console? To syslog? To nowhere? Those should be called ConsoleLog, SyslogLog and NullLog, respectively. Log is not a good name for a concrete class, because it is not a concrete name. Commented Feb 29, 2016 at 10:05
  • 20
    Personally this is exactly why I hate seeing ITheClassName, are you just creating an interface for no reason, is it just noise on top of TheClassName. If your interface has a purpose it should be possible to give it a better name than ITheClassName Commented Feb 29, 2016 at 14:27
  • 3
    The name of the class is used once (to instantiate), the name of the interface is used everywhere. Adding a letter to the interface to save letter on the class name is false economics (of characters).
    – sergut
    Commented Sep 20, 2017 at 7:14
  • @RichardTingle But I think the common usage there is simply so that MyClass has a mockable variation, right? That is, we often use interfaces to essentially make public methods really public in a fashion that allows for testing. (Not saying that's good or bad, but understanding that the motivation for interfaces is often simply to make classes that are dependencies easily mockable does explain the 1-to-1 MyClass to IMyClass mappings.)
    – ruffin
    Commented Oct 3, 2018 at 13:27
11

Most answers seem to assume that the programming language is either Java or C# where there is a concept (or keyword) for interfaces / abstract classes. In these cases, in a decent IDE, it is immediately visible with which type of class one deals and writing public interface IMyClass is unnecessary duplication. It is like you wouldn't write public final FinalMyClass - imagine putting every keyword in the classes name.

However, in my opinion in C++ the situation is a little different as one has to dive into the header file and see if the class has any virtual methods to find out if it is an abstract class. In that case, I can clearly see an argument for writing class AbstractMyClass.

So my answer would be: It depends on the programming language.

Updated 2016: 2 years of C++ experience later I would now probably consider it bad practice to prefix class names with Abstract, though I'd say there are probably code bases that are so complex that it might make sense.

6
  • Are you sure this answers the question? You might like to read the other answers and clarify some of your points.
    – david.pfx
    Commented Apr 8, 2014 at 11:10
  • C++ definitely has interfaces, even if there is no keyword for it. What do you call a class where every member function is pure virtual and there are no member variables?
    – user22815
    Commented Apr 8, 2014 at 14:51
  • @david.pfx: I think I precisely answer the question "Should interface names begin with an “I” prefix?": It depends on the programming language. If you think my elaboration is not clear enough, I am happy to improve it - which parts are not clear for you?
    – Ela782
    Commented Apr 8, 2014 at 15:39
  • 3
    @JohnGaughan: Sure it has interfaces! But my whole point is that it is about the keyword. C++ doesn't have one, so it is not visible to the IDE/user if he/she deals with an interface or not. In Java, however, it is immediately visible.
    – Ela782
    Commented Apr 8, 2014 at 15:40
  • 1
    Read the top-rating answer and compare yours. You are new to SO, and this is an opportunity to learn what kinds of answers attract votes. As it stands, yours won't. With more work, more explanation, more value, it just might. Hang in there!
    – david.pfx
    Commented Apr 8, 2014 at 22:46
8

Follow the idioms of the language you are using.

Each language has its own idioms and coding guidelines. For example, in C#, it is idiomatic to prefix interfaces with I. In Go, it is not.

1
  • +1 Follow the idioms of the language you are using. Obviously the book author is a Java developer. .NET/C#: ILog Java: Log But the disadvantage: When I like have a Log class that Implements the ILog interface .... MyLog, LogDefault, LogBase, ...? Ugly, isn't it? More ugly is: LogImpl .... :D
    – hfrmobile
    Commented Jan 11, 2018 at 10:43
3

The answer to your question in the title:

Should interface names begin with an "I" prefix?

is simply: No.

The response to the two "why" questions, one being a rewording of the other

  1. "Why should we hide the fact that some part of the code is expecting an interface?"
  2. Why should I not "leak" the details of whether a given type is an interface or a class to third-party code?

is that we don't need to hide anything. Client code, should not know or care if it is consuming an interface or using a concrete class. It must always be possible to replace the interface with an implementation of that interface whithout altering the correctness of the program. This is the Liskov Substitution Principle.

Conversely, if the code is using a concrete implementation, it is possible to refactor that and hide the implementation behind an interface.

Conformity, is the reason some give to stick with the "I" prefix, mostly in the context of C#. That is of course never a good reason. Don't go blindly do something because others do it, without questioning their rationale. People make mistakes. For the designers of the C# library, who are so old they've worked most of their career on monochrome screens, using the "I" prefix may seemed like a good idea at the time, but turned out to be a mistake.

Why interfaces must not have an "I" prefix

  • Good code is all about communication. Names must be clear and meaningful. Interface names are spread around the code base. The name of the implementing class is only visible on one line; there where the object is constructed. Therefore interface names must be kept clean and may not have an "I" prefix.

  • The I is very ugly and obnoxious. It gets even worse when the real typename starts with an I as well.

      interface IIrInstrument : IInstrument
    
      class Instrument : IIrInstrument
    

    Nobody wants abominations like this in their code base.

  • Refactoring becomes much easier when type names don't distinguish between interface and implementation. Imagine a large code base is using a concrete class called Connection. If one day a new kind of Connection comes around, one might want to use an interface instead. If that were called IConnection, this must be renamed in all the files where a Connection is used. It is much cleaner to just change the existing Connection class into the interface, and add implementations with meaningful names such as HttpConnection and DatabaseConnection. Only the lines where a connection is constructed need to change.

    For the opposite refactoring, removing the IConnection interface and replacing it with a single concrete implementation, things are even worse. One must choose between two evils of either renaming every occurrence or calling the concrete implementation IConnection which is just wrong.

  • Abstractions are difficult and choosing a clear meaningful name for them is difficult. The I prefix naming convention dictates a name that is often wrong. For example, it leads to the definition of an "IDollar" interface for a "Dollar" class, where the correct name for this concept should simply be "Currency". 1

  • The "I" prefix also leads to misinterpretation and other issues. Consider the problems with this:

      interface ISomething
      class Something : ISomething
      class MockSomething : ISomething
    
    • Something is only one implementation of ISomething, yet it is the one with the generic name, as if it was somehow special.
    • MockSomething seems to derive from Something, but it doesn't, it implements ISomething. 2

The worst that can happen is that you end up with mix in your code base with some interfaces with and some without the prefix. If that's your situation it is time to show true ownership of your code. Have trust in your compiler and unit tests and refactor those prefixes away.

8
  • To disagree: C# doesn't have multiple-inheritance. So while it's true that C#-class's basically provide a default-interface, and we might recognize those default-interface's' similarity with explicit-interface's, they can carry very different connotations due to the lack of multiple-inheritance.
    – Nat
    Commented Nov 18, 2021 at 1:58
  • In particular, if you have a choice between writing code that references a non-interface type vs. an interface type, then typically latter would be the more robust option as future objects would be more free to implement the interface while they may not be able to work with your code that referenced a non-interface type.
    – Nat
    Commented Nov 18, 2021 at 2:05
  • 1
    Yup, so we use a prefix I_ to clarify that something's an interface, such that it could be preferred. Separately, I have to say that the idea that we oughtn't worry about stuff merely because problems caused by it could be fixed through refactoring later is a bit gross; doing stuff right the first time's far preferable.
    – Nat
    Commented Nov 22, 2021 at 13:04
  • 1
    @Nat You seem really attached to your I_ prefixes. Go ahead and code like a dinosaur if you want to show of your prehistoric age. Your argument should be reversed: Implementations may have a naming convention. If you see ClassNameImpl spread around your code, all alarm bells should go off and you should think: I need to use the ClassName interface instead.
    – MathKid
    Commented Nov 26, 2021 at 16:09
  • 2
    Between the ageist comments and your alias, I get the sense that the underlying motivation here may be youthful aesthetics. There's no merit to such a position, either technically or socially; it's merely another form of bigotry.
    – Nat
    Commented Nov 26, 2021 at 21:58
1

In my (Java) code, I tend to have this convention in the APIs I expose to callers:

  • Functionality is provided through interfaces, and never by classes.
  • Non-functional parts are classes.

By non-functional, I mean things like pure data structures (such as classes that act as bridges to XML serialization or the ORM), enumerations and exceptions, all of which can't be interfaces (well, you can for the pure data classes, but it's a lot of work for very little gain as there's nothing that those classes do except hold data).

In terms of naming conventions, interfaces tend to map to either actor nouns (e.g., FooBarWatcher) or adjectives (e.g., FooBarWatchable) and both pure data classes and enumerations map to non-active nouns (e.g., FooBarStatus); the IDE can guide the API consumer without special naming conventions. Exceptions follow usual Java conventions (FooBarException, FooBarError, FooBarFault) of course.

I'll also often put the interfaces in their own package or even in their own library, just to ensure that I'm not tempted to break my own rules. (This also helps me manage the build when I'm deriving the code from external sources such as WSDL documents.)

2
  • I also never put I prefixes on interfaces. Of course it's an interface! It's in an API (or SPI)! Commented Nov 2, 2011 at 11:44
  • Please do not put any prefix in Java world as this is not a convention. In C# there is a convention to do it for a certain reasons
    – Esat Koç
    Commented Mar 7, 2023 at 20:57
0

Lots of answers address following the local/language convention’s, but none seem to touch on the cross language practice of “Accept interfaces return concrete types”. The convention of using the prefix both makes it easy to verify that this is being done, and serves as a reminder to do so.

The reason for the practice is grounded in encapsulation (the receiving function knows exactly what it needs, and shouldn’t require the sender to expose more than is necessary, while it doesn’t know what the caller needs and thus should, in general, return what it has).

So, in languages with this convention, one should definitely follow it and use the prefix.

Not the answer you're looking for? Browse other questions tagged or ask your own question.