73

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?

  • 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 2 '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 2 '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 2 '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 8 '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 at 11:03
69

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.

  • Thank you for this breakdown. +1 for the "meaningful distinctions between classes and interfaces..." – Charles Sprayberry Nov 2 '11 at 1:27
  • 25
    +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 4 '11 at 17:00
  • 4
    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 3 '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<T>.Empty or Comparer<T>.Default). – supercat Jan 13 '14 at 18:16
  • 1
    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
14

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!

  • 2
    +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 Nov 3 '11 at 9:05
  • 2
    +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 3 '11 at 10:35
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.

  • This is also mentioned in the .NET documentation – levininja Nov 6 '14 at 16:11
  • 32
    "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
  • 7
    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
  • 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 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 Oct 3 '18 at 13:27
8

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.

  • @Mat > Yes, that was a mistake of mine, and I edited it. – deadalnix Nov 1 '11 at 22:35
5

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.

  • Are you sure this answers the question? You might like to read the other answers and clarify some of your points. – david.pfx Apr 8 '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? – user22815 Apr 8 '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 8 '14 at 15:39
  • 2
    @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 8 '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 8 '14 at 22:46
4

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 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
0

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

  • I also never put I prefixes on interfaces. Of course it's an interface! It's in an API (or SPI)! – Donal Fellows Nov 2 '11 at 11:44

protected by gnat Apr 19 '17 at 20:20

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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