Pages

Wednesday, July 31, 2013

Boolean parameter VS exposing semantics

This can be a subject of quite long discussions with team mates during coffee hours.
Some team mates might think that simply putting a boolean parameter that slightly changes the behavior of a method is not a big deal. They may even make the parameter optional.

But when is that a good thing? When is it good to "just add a boolean parameter and make it optional"? Well, if it changes the method behavior in the smallest way possible, but even then it matters, then I'd say it's never good.

To prove it, consider the following two calls:

object.DoSomeLengthyWork();
object.DoSomeLengthyWork(true);

I don't know about you, but if I'm the one maintaining this code the first thing that would pop into my head when reading the second line would be "What the hell should be true?". The second thing I'd have to do would be lookup the method definition (or read its summary, if the developer who wrote the method cared enough to even create one), which is pretty easy, just position the cursor over it and press F12 right? Right! But what if that method is defined in another project / solution / dll that you do not have opened in your environment, or you don't even have access to?

And that, my friend, is why I strongly advise you to always go for the better semantics! Specially if you're writing public methods.

What I'm saying here doesn't make much sense if you work in a small company with a small codebase and maybe a team of 2 to 3 developers. But imagine working in a team of 20, 30 or 50 developers. Or even with a small codebase, imagine maintaining code that has been in production for 5 years or more, with no documentation whatsoever. Code whose owner or writer is not even working for the company anymore. I'm sure you'd have a blast trying to find out "what the hell should be true" in the example above.

Wouldn't it be easier if you could just have those two example lines written like this instead?

object.DoSomeSynchronousLengthyWork();
object.DoSomeAsynchronousLengthyWork();

"Ooooh, so that's what that true meant!"

And I won't even mention named arguments for cases like this, because they're pretty evil for distributed solutions. Jon Skeet has an awesome way of stating it, which can be found here and of course, in his book C# in Depth, that I quote:


The silent horror of changing names

In the past, parameter names haven’t mattered much if you’ve only been using C#. Other languages may have cared, but in C# the only times that parameter names were important were when you were looking at IntelliSense and when you were looking at the method code itself. Now, the parameter names of a method are effectively part of the API even if you’re only using C#. If you change them at a later date, code can break—anything that was using a named argument to refer to one of your parameters will fail to compile if you decide to change it. This may not be much of an issue if your code is only consumed by itself anyway, but if you’re writing a public API, be aware that changing a parameter name is a big deal. It always has been really, but if everything calling the code was written in C#, we’ve been able to ignore that until now.

Renaming parameters is bad; switching the names around is worse. That way the calling code may still compile, but with a different meaning. A particularly evil form of this is to override a method and switch the parameter names in the overridden version. The compiler will always look at the deepest override it knows about, based on the static type of the expression used as the target of the method call. You don’t want to get into a situation where calling the same method implementation with the same argument list results in different behavior based on the static type of a variable.


And that my friends, is why when it comes to boolean parameters VS method overloading, I always side with method overloading, that is, when the boolean parameter changes the method's behavior in a way that matters.

PS: C# in Depth is a great read, you should definitely read it.

No comments:

Post a Comment