Monday, April 24, 2006

Eating Sacred Hamburger

Software development cults tend to create sacred cows: habits and idioms that might have meant something at one time but only remain as baggage now. I tend to like to kill sacred cows and grill them up, with some nice lettuce, tomato, and a sesame seed bun. On my current project, we're actively killing some sacred cows.

Here are a couple of examples. Thankfully, Hungarian Notation has mostly been banished, except for one lingering, annoying location in the .NET world: the stupid "I" preface on interfaces. In fact, if you understand how interfaces should be used, this is exactly the opposite of what you want. In our application, every important semantic type is represented by an interface. Using interfaces like this makes it easier to do a whole host of things, including mocking out complex dependencies for testing. Why would you destroy the most important names in your application with Hungarian Notation telling you it's an interface? Ironically enough, that your semantic type is an interface is an implementation detail -- exactly the kind of detail you want to keep out of interfaces. I suspect this nasty habit developed in the .NET world because interfaces first came to the Microsoft world as COM (or, back when it started, OLE). It's a stupid cow now, and should be slaughtered.

Another sacred cow we're gleefully grilling up is the rule that all method names must use camel case. We're using this standard convention in our code, but have started using underscores for our test method names. Test methods tend to be long and descriptive, and it's hard to read long camel case names. Consider this test name:

[Test]
public void VerifyEndToEndSecurityConnectivityToInfrastructure()
vs. this version:

[Test]
public void Verify_end_to_end_security_connectivity_to_infrastructure()

Which of these is easier to read? The standard in .NET says that you use camel case, which we do...except in situations where it actually hampers productivity. If a cow gets in my way and slows me down, it's a goner.

In the book Pragmatic Programmer, Dave Thomas and Andy Hunt admonish developers to learn a new programing language every year. Seeing new ways of doing common tasks and learning new idioms is the best defense against sacred cows. Learning new languages helps you focus on how and why things work the way they do, divorced from syntax.

6 comments:

Vladimir Tuzinsky said...

Well. Although I have to agree with you about the cows, I wouldn't be so sure about the Hungarian notation. At least the original one. But I guess you've read Joel's article at http://www.joelonsoftware.com/articles/Wrong.html

Neal Ford said...

Yes, I've read Joel's comments around Hungarian, and he supports my case. Using "I" blindly is as bad as the Dark Side of Hungarian Notation. That I'm using an interface is an implementation detail. I want all my important types to be interfaces and don't want to be reminded that I'm using an interface via a smelly coding convention.

Vladimir Tuzinsky said...

Well, yes, that's clear. I too was QUITE disapointed when our "project management" decided to use IF suffix for all interfaces. This was one of the 100 reasons, why I decided to leave my current job.
I only wanted to say this is not the original Hungarian notation as Joel explains...
Anyway, nice post :) wish you a nice day

Anonymous said...

I think the concept of using "Is" for booleans (http://www.c-sharpcorner.com/effectivecs/NamingGuidelinesInNET.asp) in .net is a form of Hungarian notation also. The IDE already tells me I have a bool, why do I need the Is prefix?

Anand Vishwanath said...

"learn a new programing language every year." Trying to pair with people who have worked on other languages also helps a lot ! It brings a new perspective to the codebase.

Neal Ford said...

In the post Standard is Better than Better, mullr essentially argues that we should accept any type of foolishness in the name of consistency: if it's a standard in the language, we should just suck it up and do it. I'm not opposed to standards as long as they don't actually hamper my productivity for no benefit. Using the dreaded "I" prefix actually impacts my day to day coding. In my current project, the mandate is that every important semantic type is represented as an interface. If we used the noxious "I" prefix, that hurts Intellisense: all my important types get lumped together under the letter "I". Standards are OK, as long as they aren't based in foolish legacy. The real over-arching point of the post is to think about things like standards and apply them where they make sense.