Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've noticed a few functions I work with have 6 or more parameters, whereas in most libraries I use it is rare to find a function that takes more than 3.

Often a lot of these extra parameters are binary options to alter the function behaviour. I think that some of these umpteen-parametered functions should probably be refactored. Is there a guideline for what number is too many?

share|improve this question
    
A lot of people here saying that this isn't really the way to go with a on of parms. However what about object constructors. Taken an ORM with a class and its INIT method. I have had cases where i would need 10 or more params that have to be set to something that can't default well. I hate looking at the init function because its hard to work with and hard to remember. Is a constructor an OK edge case or is there a better way to do it? –  Ominus Apr 18 '12 at 20:24
4  
@Ominus: The idea is that you want to keep your classes focused. Focused classes usually do not have as many dependencies/attributes therefore you'd have less parameters to the constructor. Some buzz word people throw in at this point is high cohesion and single responsibility principle. If you feel that these are not violated and still need lots of params, consider using the Builder pattern. –  c_maker Apr 18 '12 at 20:31
1  
Definitely don't follow the example of MPI_Sendrecv(), which takes 12 parameters! –  chrisaycock Apr 18 '12 at 20:57
    
I updated my answer with more details about the guidelines. –  Renato Dinhani Conceição Apr 19 '12 at 1:31
4  
The project I'm currently working on uses a certain framework, in which methods with 10+ parameters is commonplace. I'm calling one particular method with 27 parameters in a couple of places. Every time I see it I die a little inside. –  perp Apr 19 '12 at 5:30

9 Answers 9

up vote 30 down vote accepted

I've never seen a guideline, but in my experience a function that takes more than three or four parameters smells like one of two problems:

  1. The function is doing too much. It should be split into several smaller functions, each which have a smaller parameter set.
  2. There is another object hiding in there. You may need to create another object or data structure that includes these parameters. See this article on the Parameter Object pattern for more information.

It's difficult to tell what you're looking at without more information. Chances are the refactoring you need to do is split the function into smaller functions which are called from the parent depending on those flags that are currently being passed to the function.

There are some good gains to be had by doing this:

  • It makes your code easier to read. I personally find it much easier to read a "rules list" made up of an if structure that calls a lot of methods with descriptive names than a structure that does it all in one method.
  • It's more unit testable. You've split your problem into several smaller tasks that are individually very simple. The unit test collection would then be made up of a behavioral test suite that checks the paths through the master method and a collection of smaller tests for each individual procedure.
share|improve this answer
4  
+1 for the parameter object pattern link. –  Shane Apr 18 '12 at 18:34
1  
Parameter abstraction has been turned into a design pattern? What happens if you have 3 parameter classes. Do you add 9 more method overloads to handle the different possible combinations of parameters? That sounds like a nasty O(n^2) parameter declaration issue. Oh wait, you can only inherit 1 class in Java/C# so that will require some more biolerplate (maybe some more subclassing) to make it work in practice. Sorry, I'm not convinced. Ignoring the more expressive approaches a language may offer in favor of complexity just feels wrong. –  Evan Plaice Apr 18 '12 at 19:10
    
Unless you use the Pattern Object pattern to package variables in an object instance and pass that in as a parameter. That works for packaging but it may be tempting to create classes of dissimilar variables just for the convenience of simplifying the method definition. –  Evan Plaice Apr 18 '12 at 19:14
    
@EvanPlaice I'm not saying that you have to use that pattern whenever you have more than one parameter - you're absolutely correct that that becomes even nastier than the first list. There may be cases where you really do need a large number of parameters and it just doesn't work to wrap them up in an object. I've yet to meet a case in enterprise development that did not fall into one of the two buckets I mentioned in my answer - that's not saying one doesn't exist though. –  Michael K Apr 18 '12 at 19:14
    
@MichaelK If you have never used them, try googling 'object initializers'. It's a pretty novel approach that significantly reduces definition boilerplate. In theory, you could eliminate a classes constructors, parameters, and overloads all in one shot. In practice though, it's usually good to maintain one common constructor and rely on the 'object initializer' syntax for the rest of the obscure/niche properties. IMHO, it's the closest you get to the expressiveness of dynamically typed languages in a statically typed language. –  Evan Plaice Apr 18 '12 at 20:20

Very much like Evan Plaice is saying, I'm a huge fan of simply passing associative arrays (or your language's comparable data structure) into functions whenever possible.

Thus, instead of (for example) this:

<?php

createBlogPost('the title', 'the summary', 'the author', 'the date of publication, 'the keywords', 'the category', 'etc');

?>

Go for:

<?php

// create a hash of post data
$post_data = array(
  'title'    => 'the title',
  'summary'  => 'the summary',
  'author'   => 'the author',
  'pubdate'  => 'the publication date',
  'keywords' => 'the keywords',
  'category' => 'the category',
  'etc'      => 'etc',
);

// and pass it to the appropriate function
createBlogPost($post_data);

?>

Wordpress does a lot of stuff this way, and I think it works well. (Though my example code above is imaginary, and is not itself an example from Wordpress.)

This technique allows you to pass a lot of data into your functions easily, yet frees you from having to remember the order in which each must be passed.

You'll also appreciate this technique when comes time to refactor - instead of having to potentially change the order of a function's arguments (such as when you realize you need to pass Yet Another Argument), you don't need to change your functions's parameter list at all.

Not only does this spare you from having to re-write your function definition - it spares you from having to change the order of arguments each time the function is invoked. That's a huge win.

share|improve this answer
    
Seeing this posted highlights another benefit of the pass-a-hash approach: notice that my first code example is so long it generates a scrollbar, while the second fits cleanly on the page. The same will likely be true in your code editor. –  chrisallenlane Apr 24 '12 at 19:28

One aspect that the other answers do not take up is performance.

If you are programming in a sufficiently low level language (C, C++, assembly) a large number of parameters can be quite detrimental to performance on some architectures, especially if the function is called a large amount of times.

When a function call is made in ARM for instance, the first four arguments are placed in registers r0 to r3 and remaining arguments have to be pushed onto the stack. Keeping the number of arguments below five can make quite a difference for critical functions.

For functions that are called extremely often, even the fact that the program has to set up the arguments before each call can affect performance (r0 to r3 may be overwritten by the called function and will have to be replaced before the next call) so in that regard zero arguments are best.

share|improve this answer
    
Fascinating. Thank you. –  user973810 Apr 19 '12 at 15:26

If the domain classes in the application are designed correctly, the number of parameters that we pass into a function will be automatically reduced - because the classes know how to do their job and they have enough data to do their work.

For example, if you have manager class which asks a 3rdgrade class to complete the assignments.

If you model correctly,

3rdGradClass.finsihHomeWork(int lessionId) {
           result = students.assignHomework(lessonId, dueDate);
           teacher.verifyHomeWork(result);
}

This is simple.

If you dont have the correct model, the method will be like this

Manager.finsihHomework(grade ,  students, lessionId , teacher etc) {
           .... // This is not good.
}

The correct model always reduces the function parameters between the method calls as the correct functions are delegated to their own classes ( Single responsibility) and they have enough data to do their work.

Whenever I see the number of parameters are increasing, I check back my model if I did my modelling correctly.

There are som exceptions though: When I need to create a transfer object or config objects , I will use a builder pattern to produce small built objects first before constructing a big config object.

share|improve this answer

According to "Clean Code: A Handbook of Agile Software Craftsmanship", zero is the ideal, one or two are acceptable, three in special cases and four or more, never!

The words of the author:

The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.

In this book there is a chapter talking only about functions where parameters are large discussed, so I think this book can be a good guideline of how much parameters you need.

In my personal opinion, one parameter is better than no one because I think is more clear what is going on.

As example, in my opinion the second choice is better because is more clear what the method is processing:

LangDetector detector = new LangDetector(someText);
//lots of lines
String language = detector.detectLanguage();

vs.

LangDetector detector = new LangDetector();
//lots of lines
String language = detector.detectLanguage(someText);

About a lot of parameters, this can be a sign that some variables can be grouped into a single object or, in this case, a lot of booleans can represent that the function/method is doing more that one thing, and in this case, is better refactoring each one of these behavior in a different function.

share|improve this answer
3  
"three in special cases and four or more, never!" BS. How about Matrix.Create(x1,x2,x3,x4,x5,x6,x7,x8,x9); ? –  lukas Apr 19 '12 at 2:26
14  
Zero is ideal? How the heck do functions get information? Global/instance/static/whatever variables? YUCK. –  alpha123 Apr 19 '12 at 3:13
5  
That's a bad example. The answer is obviously: String language = detectLanguage(someText);. In either of your cases you passed the exact same number of arguments, it just happens that you've split the function execution in two because of a poor language. –  Matthieu M. Apr 19 '12 at 6:20
3  
@lukas, in languages supporting such fancy constructs as arrays or (gasp!) lists, how about Matrix.Create(input); where input is, say, a .NET IEnumerable<SomeAppropriateType>? That way you also don't need a separate overload when you want to create a matrix holding 10 elements instead of 9. –  Michael Kjörling Apr 19 '12 at 7:49
    
@MatthieuM. I edited the example to clarify a bit my example. The main point is the parameter in the method, not in the constructor. When the constructor is far from the method becomes harder to understand what the method is processing when there aren't any parameters. –  Renato Dinhani Conceição Apr 19 '12 at 10:21

When the parameter list grows to more than five, consider defining a "context" structure or object.

This is basically just a structure that holds all the optional parameters with some sensible defaults set.

In the C procedural world a plain structure would do. In Java, C++ a simple object will suffice. Don't mess with getters or setters because the sole purpose of the object is to hold "public"ly settable values.

share|improve this answer
    
I agree, a context object can turn out to be very handy when function parameter structures start becoming rather complex. I had recently blogged about using context objects with a visitor-like pattern –  Lukas Eder Apr 19 '12 at 11:56

No, there is no standard guideline

But there are some techniques that can make a function with a lot of parameters more bearable.

You could use a list-if-args parameter (args*) or a dictionary-of-args parameter (kwargs**)

For instance, in python:

// Example definition
def example_function(normalParam, args*, kwargs**):
  for i in args:
    print 'args' + i + ': ' + args[i] 
  for key in kwargs:
    print 'keyword: %s: %s' % (key, kwargs[key])
  somevar = kwargs.get('somevar','found')
  missingvar = kwargs.get('somevar','missing')
  print somevar
  print missingvar

// Example usage

    example_function('normal parameter', 'args1', args2, 
                      somevar='value', missingvar='novalue')

Outputs:

args1
args2
somevar:value
someothervar:novalue
value
missing

Or you could use object literal definition syntax

For example, here's a JavaScript jQuery call to launch an AJAX GET request:

$.ajax({
  type: 'GET',
  url: 'http://someurl.com/feed',
  data: data,
  success: success(),
  error: error(),
  complete: complete(),
  dataType: 'jsonp'
});

If you take a look at jQuery's ajax class there are a lot (approximately 30) more properties that can be set; mostly because ajax communications are very complex. Fortunately, the object literal syntax makes life easy.


C# intellisense provides active documentation of parameters so it's not uncommon to see very complex arrangements of overloaded methods.

Dynamically typed languages like python/javascript have no such capability, so it's a lot more common to see keyword arguments and object literal definitions.

I prefer object literal definitions (even in C#) for managing complex methods because you can explicitly see which properties are being set when an object is instantiated. You'll have to do a little more work to handle default arguments but in the long run your code will be a lot more readable. With object literal definitions you can break your dependence on documentation to understand what your code is doing at first glance.

IMHO, overloaded methods are highly overrated.

Note: If I remember right readonly access control should work for object literal constructors in C#. They essentially work the same as setting properties in the constructor.


If you have never written any non-trivial code in a dynamically typed (python) and/or functional/prototype javaScript based language, I highly suggest trying it out. It can be an enlightening experience.

It's can be scary first to break your reliance on parameters for the end-all, be-all approach to function/method initialization but you will learn to do so much more with your code without having to add unnecessary complexity.

Update:

I probably should have provided examples to demonstrate use in a statically typed language but I'm not currently thinking in a statically typed context. Basically, I've been doing too much work in a dynamically typed context to suddenly switch back.

What I do know is object literal definition syntax is completely possible in statically typed languages (at least in C# and Java) because I have used them before. In statically typed languages they're called 'Object Initializers'. Here are some links to show their use in Java and C#.

share|improve this answer
3  
I'm not sure I like this method, mainly because you lose the self documenting value of individual parameters. For lists of like items this makes perfect sense (for instance a method that takes a list of strings and concatenates them) but for an arbitrary parameter set this is worse than the long method call. –  Michael K Apr 18 '12 at 18:37
    
@MichaelK Take another look at object initializers. They allow you to explicitly define properties as opposed to how they're implicitly defined in traditional method/function parameters. Read this, msdn.microsoft.com/en-us/library/bb397680.aspx, to see what I mean. –  Evan Plaice Apr 18 '12 at 18:55
2  
Creating a new type just to handle the parameter list sounds exactly like the definition of unnecessary complexity... Sure, dynamic languages let you avoid that but then you get a single ball of goo parameter. Regardless, this doesn't answer the question asked. –  Telastyn Apr 18 '12 at 19:11
    
@Telastyn What are you talking about? No new type was created, you declare properties directly using object literal syntax. It's like defining an anonymous object but the method interprets it as a key=value parameter grouping. What you're looking at is a method instantiation (not a parameter encapsulating object). If your beef is with parameter packaging, take a look at the Parameter Object pattern mentioned in one of the other questions because that's exactly what it is. –  Evan Plaice Apr 18 '12 at 19:18
    
@EvanPlaice - Except that static programming languages by-and-large require a (often new) declared type in order to allow the Parameter Object pattern. –  Telastyn Apr 18 '12 at 19:30

Ideally zero. One or two are ok, three in certain cases.
Four or more is usually a bad practice.

As well as the single responibility principles that others have noted you can also think of it from testing and debugging perspectives.

If there is one parameter, knowing it's values, testing them and finding error with them is 'relatively easy as there is only one factor. As you increase the factors, the total complexity increases rapidly. For an abstract example:

Consider a 'what to wear in this weather' program. Consider what it could do with one input - temperature. As you can imagine, the results of what to wear are pretty simple based on that one factor. Now consider what the program might/could/should do if it is actually passed temperature, humidity, dewpoint, precipitation, etc. Now imagine how hard it would to debug if it gave the 'wrong' answer to something.

share|improve this answer
7  
If a function has zero parameters, it's either returning a constant value (useful in some circumstances, but rather limiting) or it is using some concealed state that would be better off made explicit. (In OO method calls, the context object is sufficiently explicit that it doesn't cause problems.) –  Donal Fellows Apr 18 '12 at 20:55
1  
-1 for not quoting the source –  Joshua Drake Apr 19 '12 at 13:31
    
Are you seriously saying that ideally all functions would take no parameters? Or is this hyperbole? –  GreenAsJade 2 hours ago
    
See Uncle Bob's argument at: informit.com/articles/article.aspx?p=1375308 and note that at the bottom he says "Functions should have a small number of arguments. No argument is best, followed by one, two, and three. More than three is very questionable and should be avoided with prejudice." –  Michael Durrant 2 hours ago

Personally, more than 2 is where my code smell alarm triggers. When you consider functions to be operations (that is, a translation from input to output), it is uncommon that more than 2 parameters are used in an operation. Procedures (that is a series of steps to achieve a goal) will take more inputs and are sometimes the best approach, but in most languages these days should not be the norm.

But again, that's the guideline rather than a rule. I often have functions that take more than two parameters due to unusual circumstances or ease of use.

share|improve this answer

protected by gnat Mar 17 at 11:53

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.