98

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?

Aaronaught
  • 44,005
  • 10
  • 92
  • 126
Charles Sprayberry
  • 1,606
  • 1
  • 12
  • 21
  • 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 Nov 02 '11 at 10:11
  • 3
    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 Nov 02 '11 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 Nov 02 '11 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 Apr 08 '14 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 May 13 '19 at 11:03
  • Duplicate of this question: https://stackoverflow.com/questions/5816951/prefixing-interfaces-with-i This one has also been reading the 'clean code' book. – MathKid Jan 11 '22 at 08:54

8 Answers8

92

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.

Aaronaught
  • 44,005
  • 10
  • 92
  • 126
  • Thank you for this breakdown. +1 for the "meaningful distinctions between classes and interfaces..." – Charles Sprayberry Nov 02 '11 at 01:27
  • 38
    +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 Nov 04 '11 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 Sep 03 '12 at 11:47
  • 3
    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.Empty` or `Comparer.Default`). – supercat Jan 13 '14 at 18:16
  • 3
    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 Jan 22 '15 at 22:54
  • *Interface members cannot have access modifiers (all members are "public");* I've designed many interfaces with methods like `public String getX();` and `public void setX(String x);" – Tulains Córdova Feb 29 '16 at 11:59
  • 2
    @jsj C++ has full MI, so the distinction is even more academic. – Deduplicator Nov 17 '21 at 23:52
21

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!

Jim Nutt
  • 497
  • 3
  • 5
  • 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](http://xkcd.com/163/) – Bringer128 Nov 03 '11 at 09:05
  • 4
    +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. Nov 03 '11 at 10:35
13

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.

user
  • 2,703
  • 18
  • 25
deadalnix
  • 5,973
  • 2
  • 31
  • 27
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.

CodeART
  • 3,992
  • 1
  • 20
  • 23
  • This is also mentioned in the .NET [documentation](http://msdn.microsoft.com/en-us/library/8bc1fexb(v=vs.71).aspx) – levininja Nov 06 '14 at 16:11
  • 61
    "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. – Sebastian Redl Feb 29 '16 at 10:05
  • 14
    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 – Richard Tingle Feb 29 '16 at 14:27
  • 1
    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 Sep 20 '17 at 07: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 Oct 03 '18 at 13:27
  • @SebastianRedl you can have abstract Log class i guess. – Juri Jul 30 '19 at 12:30
  • Personally, I don't use `I` to denote things because I prefer to be explicit. In this case, I'd likely do `interface LogRaw` or `interface LogArgs` and `class Log`. One denotes args, the other (raw) means "it can be directly saved to disk" – Seph Reed Jun 28 '21 at 19:55
9

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.

Ela782
  • 191
  • 1
  • 3
  • Are you sure this answers the question? You might like to read the other answers and clarify some of your points. – david.pfx Apr 08 '14 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? –  Apr 08 '14 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 Apr 08 '14 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 Apr 08 '14 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 Apr 08 '14 at 22:46
7

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.

Pete
  • 8,916
  • 3
  • 41
  • 53
  • +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 Jan 11 '18 at 10:43
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.)

Donal Fellows
  • 6,347
  • 25
  • 35
  • I also never put `I` prefixes on interfaces. Of _course_ it's an interface! It's in an API (or SPI)! – Donal Fellows Nov 02 '11 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 – hq-coder Mar 07 '23 at 20:57
1

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.

MathKid
  • 119
  • 2
  • 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 Nov 18 '21 at 01: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 Nov 18 '21 at 02:05
  • To be fair, there is something a tad old-fashion about having to use the prefix `I_`; in principle, it'd be nicer if an IDE would instead auto-insert such a qualifier, or otherwise communicate it through a user-configurable mode (e.g., code-coloring, if the user prefers), rather than a naming-convention having to be obeyed. – Nat Nov 18 '21 at 02:08
  • @Nat Agreed that it is almost always better to use an interface than a concrete class. That is however, completely irrelevant to this question. The discussion here is merely about what name to use for your interfaces. – MathKid Nov 22 '21 at 12:38
  • @Nat It would be nice if an IDE can distinguish and show the use of interfaces in the client code. But as explained in the first part of this answer, it is not necessary. Client code may always assume it's consuming an interface, even when using a concrete class, as it could be refactored later. The LSP tells us it just doesn't matter. Client code does not need to know whether a type is a concrete class or an interface, and therefore an IDE (or name prefix) does not need to show it. – MathKid Nov 22 '21 at 12:48
  • 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 Nov 22 '21 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 Nov 26 '21 at 16:09
  • 1
    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 Nov 26 '21 at 21:58