Prefer Additional Methods Over Additional Overloads

June 20th, 2010

If you have ever written code that is going to be used as an API for other programmers, you may start to think about writing code in a different viewpoint from what you normally do.

Most of us write code for the purpose of achieving a goal.  If we practice writing elegant code, we are conscious of making that code as readable and terse as possible.

Seldom do we think about the use of our code from an API standpoint.

There is a subtle difference between designing your code in a way that will make it easier for someone else to maintain, and designing your code in a way that will make it easier for someone else to use.

Intellisenselessness

How often are you working against some API and you type a method name you want to use only to have intellisense present you with 5 overloads for the method all with several different parameters choices?

LoginOverloads

Which one do you use?  It is hard to be sure, you end up having to read through the long lists of parameters to figure out what method you should call and what parameters you should pass it.

Wouldn’t it be better if you were presented with what the method does in the method name rather than guessing what it does in the parameter list?  Something like this?

LoginMoreMethods

Perspective

From the perspective of the person writing the Login method(s), overloads probably seem like the most efficient and correct way to implement the multiple ways the method can be called.

From the perspective of the person using the Login method(s), additional methods are much preferred, because they are easier to understand and know what you are looking for.

Try to think from the perspective of someone using your code when writing your code.

Extract boolean parameter to two methods

I want to take a look at a very specific example that can be of great benefit to the readability and use of your code.

Take a look at this code below.

   1: public void Login()

   2: {

   3: }

   4:  

   5: public void Login(bool rememberMe)

   6: {

   7: }

Seems like a fine overload of a Login method.  I have written code just like this, you probably have also. 

 

Unfortunately, by adding this overload, we have added some complexity to our API, because now the user of that code has to see that there is an additional overload that take a bool parameter called rememberMe.

Consider this longer alternative.

   1: public void LoginRememberMe()

   2: {

   3: }

   4:  

   5: public void LoginDoNotRememberMe()

   6: {

   7: }

Instead of overloading Login and making the user have to decide which overload to call and pass in a parameter, we have elected to create two differently named methods which take 0 parameters and clearly state what they are going to do.

I’m not saying you should never write overloads, but anytime you see an overload in your code base, you should stop and think if it would be more clear to make that overloaded method into two different methods that can eliminate one or more of the parameters.

Any time you are restricting the number of choices someone using your code has to make, you are making that code simpler to use.

If you don’t believe me, consider why the iPhone has only one button.

As always, you can subscribe to this RSS feed to follow my posts on elegant code.  Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week.  Also, you can follow me on twitter here.

  • http://elegantcode.com/about/john-sonmez/ John Sonmez

    @John Atwood
    I definitely have to agree with you there John. Good example. Yes, if the overload does exactly the same thing and only differs in type, it should be an overload rather than an additional method.

  • http://elegantcode.com/about/john-sonmez/ John Sonmez

    @Henning Anderssen
    Good point!

    I agree wholeheartedly with your reasoning and example.
    In fact my next post is going to be on constraining user input through the use of custom parameter classes.

    I don’t think what I am talking about in my post and what you are saying here are necessarily mutually exclusive though. It kind of depends on the situation and what data your storing and how your API is interacted with. I could easily see a login method that takes in a fullName, but is an additional method instead of an overload.

    I agree also that you can store parameters in the class instance, but you will still have to get them in there somehow. Which can jump move the problem up to overloaded constructors.

    Good points though excellent discussion.

  • http://www.truewill.net/myblog/index.php Bill Sorensen

    I agree with your refactoring; I think the code smell is the Boolean parameter, though. If your method has a Boolean parameter, it’s probably doing more than one thing (thus violating SRP). Enum parameter types are also potential code smells.

  • Sebastian Schuth

    “Try to think from the perspective of someone using your code when writing your code” – There is an easy way to do this: write tests first, and you’ll see if using teh api over and over again in different contexts is making sense.