- ok AIC was a bit to depressing moving on to... youtube.com/watch?v=rCVQoG… 20 hours ago
- my sample lol while working on the #cheezburger content card.. i<3 @github http://t.co/03Bc0hEW 20 hours ago
- little AIC jar of flies & hacking on some less styles while sipping a fine brew from Olympia Coffee Roasting Company #goodmorning #cheezlife 21 hours ago
- hey @marthakelly have you met @garannm? she is also a big javascript fan... 1 day ago
- woot looks like i get to spend a week working with the Know Your Meme team haxoring on some ruby in the near future. 1 day ago
I Am Not Myself
Bills.Pay(Developer.Skills).ShouldBeTrue()
Why drop the I if you’re going to just add an Impl?
Posted by on April 26, 2011
I was perusing the TopShelf source code this morning, trying to track down a change in the hosting API, when I discovered that the TopShelf team has succumbed to the new drop the ‘I’ in interface names meme. It’s new to the .NET scene anyway, the java guys have been doing it for a while like all new good ideas in .NET. That were not stolen from ruby anyway.
If you are unfamiliar, the gist of the meme is it is unnecessary to add the ‘I’ in front of an interface name because the consumer of the interface does not care that it is an interface and the ‘I’ is a form of Hungarian notation that the civilized world has all agreed is a bad practice.
So your..
public interface ISomeBehavior { }
..should be..
public interface SomeBehavior { }
And this makes a kind of sense. Where it breaks down is when you see a class that implements the interface that is named like this.
public interface SomeBehavior { }
public class SomeBehaviorImpl { }
I am not quite sure what benefit is in moving the ‘I’ from the interface to the implementation and adding three characters. What have I gained beyond adding to my carpel tunnel? Does my consuming code care somehow that that this is an implementation of some ‘I’-less interface?
At some fundamental level, an interface is a contract. That contract states that the class that implements the interface provides an specific usable set of methods and properties. An other way to look at this is that the interface is a behavior.
Consider the IDisposable interface provided by .NET. There is no DisposableImpl floating around. The interface describes a characteristic of the implementing type, that it behaves like a disposable thing.
Your interfaces need not be a one to one relationship with the implementing class. In fact, your classes can implement multiple SRP friendly interfaces. To quote Brett L. Schuchert:
class Manager : public ISing, public IDance {}
Keep your interfaces clean, let the managers violate all they want
So, I am sure you making angry face at my blog right now thinking, “Ok, mister smarty pants, what should I do then.”
To that I say, I like the ‘I’, but I use it so that it reads like a declaration.
public interface IReadFiles { }
public interface ICalculateRates { }
public interface ISingAndDance {//OMG SRP VIOLATION!}
And you may find that as preposterous as I find the ‘I’/'Impl’ meme. But that’s cool. To each his own, but that damn ‘Impl’ stuff is not mine.
This post brought to you by Negatron.
It is better to have a clean interface-name than an implementation-name, because you usually use the interface-name more often. Plus, the place where you use the interface-name, it’s usually not very important if it’s an interface, an abstract class or a regular class. It’s the actual behavior/responsibility that’s interesting.
In my experience, the SomeBehavior/SomeBehaviorImpl pairing (where you don’t have other implementations) doesn’t really happen very often. That’s mostly when you thought you needed an interface, but then you didn’t, and you haven’t refactored yet. When I do see the interface-name with “Impl” added, it’s usually because it’s the default implementation. The alternatives may be used relatively rarely, or may be for automated testing.
By the way, I think interfaces is for responsibilities. The behavior is in the implementation. This may hint at why you see the SomeBehavior/SomeBehaviorImpl pairing often enough to care about it.
To me that I means a lot. It tells me I’m dealing with an abstract interface and I need to search for an implementation.
In .NET one of the core principles is “Scenario-Driven Design”. In Scenario-Driven Design the developer using your API is supposed to be able to follow this pattern for the normal, everyday use of your classes.
1. Create an instance of the class
2. Initialize its properties (perferablly as few as possible, use defaults where possible)
3. Call one or more methods
If I have to start mucking about with abstract interfaces and factories for basic functionality then my upstream developer has failed me.
Something I interesting is that the guidelines for .NET API design explicitly states “Do not rely solely on standard design methodologies when designing the public API layer of a framework.” Then it goes on to explain why they believe that that usability concerns trumps OOD methodologies.
I’m pretty sure there is still an interface in the code base of my previous company named ICanHas. I could not resist the temptation.
Good point.. This triggered some conversation in our team when we saw the uncle bob’s clean code presentation the other day.. I like having to identify the interfaces by their names.. One other way to name them is decorating them with a ‘able’ to the behavior.. Few examples Disposable, Singable, Readable.. This implies that the interface is a behavior.
It seems to me that the most popular reason to follow the IThing/Thing pattern is to achieve a Separated Interface. I see this most of the time with a layered architecture. In that case, more likely than not, the only type that will need to reference both IThing and Thing is Thing itself. That being the case, why not just name them both Thing, rely on the two types being in different namespaces, and alias the interface in your implementation?
using IThing = MyApp.Thing;
namespace MyApp.Core.Thing
{
public class Thing : IThing
{
...
}
}
I agree.
The most frequent place I run into one-to-one interface implementation pairs is on the boundaries of systems. Often when integrating with another system: persistence, external shipping companies, blah blah blah and it also fulfills that good’ole testing need. I prefer not to use Impl, but some people believe they need it to embed reminders of some technical quality/order/organization of the system. Personally I think that is using the wrong tool to communicate, but as you said, “to each their own.”