On prefixes and suffixes

Lately I’m doing a bit of C# programming, as I’m having fun with the Unity game engine and suite (and boy, it is cool!). Unity allows you to write game logic in C#, JavaScript and Boo.
I started with JavaScript, but then I switched to C#, just for the sake of it.

There I had quite a surprise. C# base libraries (and thus, I would expect, most of C# code out there) prefix interfaces with “I”!!


IList, IDictionary, IWhatever.

When C# first came out and later on as new versions appeared I glanced at the language features and I liked what I saw, especially since C# seemed far bolder than Java in updating its syntax to new features, and doing it well (my feelings where kind of confirmed when Neal Gafter moved over to Microsoft to work on .NET).

That said, finding this naming convention so deeply rooted in C# culture pains me to no end.

I’ve had a look around and I saw quite a few blogs criticizing it, yet the real point about why the “I” for Interface is not a good idea didn’t appear very often, and when it did, it seemed like an afterthought.

I will express this point with a question : “Why would a client ever need to know that some type it is using is an interface?”.

“Client” here means any bit of code using some other bit of code :


oneMethod() {
IList list = new ArrayList();

In this exemple “oneMethod” is the client of the list.


anotherMethod(IList list) {
list.doSomething();
}

Here again, another method is a client of the list.

For the purpose of expressing a problem’s domain and the logic for solving it, advertising the fact that IList is an interface is uninteresting.
The client code using an interface has no need to know about it, nor the developer reading that code!

What is even more important is that prefixing the interface shows that the interface is considered just a technical “trick”, a convenient, but meaningless literal which happens to be part of the language.

Interfaces must always represent the core roles of a system, the main actors on stage. They must do so crisply and unambiguously, as those are the actors we will spend most of our time looking at.

If my system sends payments over the network I do expect that the main roles get first-class names : Payment, Connection, Customer.
If some of these happen to be interfaces I do expect their implementations to get second-class, specific names, since I won’t look at them often, unless I need to delve one step lower in the details : DirectPayment, DelayedPayment, TCPConnection, BankCustomer, InsuranceCustomer…

When observing “I” infested code I notice that the first-class name (Customer, Connection..) is given to the main implementation of the interface, or, worse, the sole implementation of the interface. In this case the interface is perceived as boilerplate (and it is likely so) : I need to have an interface, so let’s extract it and put a convenient prefix before it.

Other times the use of prefixes seems to arise from having apparently expended all “good” names. I stress the “apparently” : I’ve yet to find a case where it is impossible to give both a meaningful name to the interface, representing the overall concept for the system, and to the implementations, representing the details.

Provided that one stops to think long enough.

Finding good names needs time. A serious naming effort is often the beginning of a new understanding; usually that’s the understanding that our roles are wrong and we should look for better ones, which leads to further costs.

By using plenty of prefixes and suffixes instead (I, A, Manager, Processor, Decorator, Impl, Service, Factory, Bean…), we can write code much faster, it spares us much of the thinking, in fact, most of the time we can just stop thinking about names, almost anything can be forced to fall within the range of a random combination of prefixes and suffixes :


ITransferManager, ProcessorService, ServiceFactory, ProcessorDecoratorImpl

and, of course, DecoratorProcessorImpl !

While here is a sample of what we might be missing (traslating 1 on 1 to meaningful names) :


PostOffice, MailBox, MailAccount, RemoteMailBox, UnsortedMail

By using prefixes and suffixes we are truly wasting the semantic potential of our code.

It’s the same kind of waste that we could obtain by naming functions after the number of their parameters : setString1(“”), setString2(8,””).

We wouldn’t dream of not naming the second setString as what it actually is : setSubstring.
Yet we do so all the time with classes.

Often we do this for the sake of “standardization”. This a classic of groups where a chief developer puts down the architecture and then enforces a set of rules for class names : “And thou shall call ye spring initialised objects “Beans”, and those which are not shall be “Factories”…”.

Standardization is nice, and it is perhaps the only positive point I see in pattern-based prefixes and suffixes, but the standardization effort happens long before the real domain of the system is clear and has slowed down evolving; this leaves the standardization authority with pretty few clues on proper names and so it falls back to enforcing technical roles. The developers behind the lead will have one less reason to look for good names : they are not expected to do so.

So, to sum it all up, when prefixes and suffixes see large use, the favoured programming habit is often “write fast, read slow”. This is the recipe for huge, bloated code, where technical details get advertised everywhere and arise to prominence in spite of the problem domain. And I don’t like it.

I’m looking at you, Controller.