This IConvention is an interesting one: “Let’s prefix all interfaces with a capital I.” Who thought of this? Why did they think it was a good idea?
Let’s say I want to implement the Command pattern in C#. I create the following interface…and to be true the fathers of C# I use the IConvention.
In my application I can now write Code like this.
Clearly, every object in the IList
of commands is an Implementation of ICommand
. And ICommand
is an Interface because it starts with an I. That’s important to know because if it didn’t have the I, it might be an abstract class or even a concrete class.
And if that were the case then…well…hmmm…it doesn’t really matter. I could call the class ICommand
or I could call it Command
. From the point of view of the client code, maybe Command
it’s an interface or maybe it’s not.
So if it’s all the same, I might as well submit to the convention and call it ICommand
. Right?
Wrong! Prefixing interfaces with I is a mistake and this is why…
Assume that I really do need a Command abstraction. Should it be an interface or an abstract class?
I can’t think of any logic to put in the base class and the Dependancy Inversion Principles says interfaces are preferred. So I’ll make it an interface and follow the IConvention naming it ICommand
.
After a while there are a dozen or so implementations of ICommand
in the application. New implementations are popping up all the time. One day I realize that the application needs to know whether an ICommand
has executed or not.
Since this affects all implementations of ICommand
I can add another method to the interface:
However, it’s not long before I realize that all the derived classes implement the Executed
property with the exact same code.
They also need a boolean field. So to avoid duplicate code, I’ll use Template Method like so:
But wait! ICommand
is not longer an interface. I can’t just leave that I sitting there. Clients will think it’s still an interface. So now I need to rename the class to Command
without the I. Fortunately, !-ReSharper-!
will help me there.
But now I’ve got the Command
class in a file named ICommand.cs
. Renaming the file is a bit more challenging since it has to be changed in source control as well.
So I rename the file in the subversion repository, then remove the ICommand.cs
file from the Visual Studio project, and finally add the new Command.cs
file to the project…whew. That silly I sure causes a good deal of hurt.
I’ve stumble over this scenario more times than I care to mention. Experience has taught me that prefixing interfaces with an I is a choice that will come back and haunt me. So I don’t do it.
Here’s my dilema. Maybe you can help me. I’ve been translating Unclebob’s Agile Software Development book into C#. In the code examples I have heeded my experience and created interfaces without the I prefix. Reviewers don’t like this.
They keep telling me that I need to add the I prefix. I’m torn. I feel in my heart of hearts that using the IConvention does more harm than good. Yet, readers of the book will be familiar with the IConvention and may be confused by examples that don’t use it. What’s the right thing to do?