228

Routines can have parameters, that's no news. You can define as many parameters as you may need, but too many of them will make your routine difficult to understand and maintain.

Of course, you could use a structured variable as a workaround: putting all those variables in a single struct and passing it to the routine. In fact, using structures to simplify parameter lists is one of the techniques described by Steve McConnell in Code Complete. But as he says:

Careful programmers avoid bundling data any more than is logically necessary.

So if your routine has too many parameters or you use a struct to disguise a big parameter list, you're probably doing something wrong. That is, you're not keeping coupling loose.

My question is, when can I consider a parameter list too big? I think that more than 5 parameters, are too many. What do you think?

Auron
  • 13,626
  • 15
  • 47
  • 54

34 Answers34

162

When is something considered so obscene as to be something that can be regulated despite the 1st Amendment guarantee to free speech? According to Justice Potter Stewart, "I know it when I see it." The same holds here.

I hate making hard and fast rules like this because the answer changes not only depending on the size and scope of your project, but I think it changes even down to the module level. Depending on what your method is doing, or what the class is supposed to represent, it's quite possible that 2 arguments is too many and is a symptom of too much coupling.

I would suggest that by asking the question in the first place, and qualifying your question as much as you did, that you really know all of this. The best solution here is not to rely on a hard and fast number, but instead look towards design reviews and code reviews among your peers to identify areas where you have low cohesion and tight coupling.

Never be afraid to show your colleagues your work. If you are afraid to, that's probably the bigger sign that something is wrong with your code, and that you already know it.

Dan
  • 61,568
  • 9
  • 61
  • 78
Nick
  • 5,875
  • 1
  • 27
  • 38
  • A good **rule-of-thumb** is the number of CPU registers, because anymore and the compiler will be forced to allocate them on the stack. – Michaelangel007 Mar 31 '16 at 14:10
  • 1
    @Michaelangel007 regarding the answer you are commenting you should not say that, because it tells that there is no rule. Furthermore, the number of parameters is a matter of readability, not performance. – clemp6r Sep 08 '16 at 07:36
  • 1
    @clemp6r Incorrect -- it is **both**. Compilers guys have to deal with "register spill" all the time. The _only_ authoritative answer is to inspect the assembly of what your compiler is generating. The numbers of registers doesn't magically change on the _same_ platform. https://en.wikipedia.org/wiki/Register_allocation – Michaelangel007 Sep 09 '16 at 15:11
124

A function can only have too many parameters if some of the parameters are redundant. If all the parameters are used, the function must have the correct number of parameters. Take this often used function:

HWND CreateWindowEx
(
  DWORD dwExStyle,
  LPCTSTR lpClassName,
  LPCTSTR lpWindowName,
  DWORD dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  HWND hWndParent,
  HMENU hMenu,
  HINSTANCE hInstance,
  LPVOID lpParam
);

That's 12 parameters (9 if you bundle the x,y,w and h as a rectangle) and there's also the parameters derived from the class name as well. How would you reduce this? Would you want to reduce the number more to the point?

Don't let the number of parameters bother you, just make sure it's logical and well documented and let intellisense* help you.

* Other coding assistants are available!

ks1322
  • 33,961
  • 14
  • 109
  • 164
Skizz
  • 69,698
  • 10
  • 71
  • 108
  • Why do you have to specify so many things when you create a window? Can't you specify that later in the code? – Auron Oct 06 '08 at 16:45
  • 37
    I'm voting this up. I am amazed at all the other answers saying "3" and "4"! The correct answer is: the minimum necessary, which can sometimes be quite a few. – Tony Andrews Oct 06 '08 at 16:49
  • 1
    @Auron - I've seen system like the type your are talking about. They were horrible because people the act of setting those parameters later in the code required the window to be destroyed and recreated. It was very slow. – Torlack Oct 06 '08 at 16:50
  • 1
    @Auron - that function is from the Win32 API. The window can be drawn before the function returns so all the parameters are necessary. – Skizz Oct 06 '08 at 16:54
  • Ok, I find that in very specific cases, like a call to an OS API, a long parameter list is acceptable. – Auron Oct 06 '08 at 17:06
  • 16
    If that function were designed today it would probably look a little different. x, y, nWidth and nHeight can be bundled in a Rectangle object. style and xStyle could be combined into a set of enums or strings. Now you have only 8 parameters. – finnw Oct 06 '08 at 17:07
  • "Now you have only 8 parameters." Exactly! Double the maximum stated by others. @Skizz - I agree with you on this one. – Jeffrey L Whitledge Oct 06 '08 at 20:06
  • 16
    @finnw If that function were designed today? It already has been redesigned. Form f = new Form(); has 0 parameters. – Nick Oct 06 '08 at 20:24
  • 2
    @Nick Guess what is called inside f.show() ? :) Easy to wrap this stuff up and make it warm and cuddly. –  Oct 24 '09 at 10:13
  • 36
    This is C **and** winapi. I can't think of a worse example. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Oct 13 '11 at 19:32
  • 17
    No, no. This is procedural style. Windows are objects, so this is obsolette now. Today, this would be solved with aggregated classes, not with bunch of parameters. The intuitive rule of good design is *if you can not describe function (including parameters) in one simple sentence, it is poorly designed*. I believe this is the case. – Jan Turoň Jun 12 '12 at 09:03
  • 2
    This code comes from ancient times from nerds proudly producing obfuscated code. Even the name of the function is bad: what does the *Ex* mean? Exclusive, execute, exclude, exception? If this would be good design, no MFC or .NET were created. – Jan Turoň Jun 12 '12 at 09:13
  • I feel obliged to point out that all the window styles in this call are already bundled into a neat DWORD; otherwise it would have had many more parameters. Oh, and @JanTuroň, you missed the correct meaning of Ex intentionally, didn't you? – Mr Lister Mar 29 '13 at 11:10
  • 1
    +1 @JanTuroň, if you're passing this many arguments you should consider whether some of them are conceptually tied together and would suit an aggregate class (eg Rect as mentioned by finnw) – Alex Apr 15 '13 at 09:04
  • 4
    Folks, don't forget: this code was probably written around 1987, before things like Object-oriented programming were common for UI. While OOP doesn't drag down a system like a Core i5, we're talking systems like a 286. – Joe Plante Feb 04 '14 at 20:35
  • if I write code like in this style, the problem I see that functions become very long in height but do not do much. For exmaple I have about 15 parameters and if I would want to add more filters to the form, the parameter count would become even bigger – Dariux Mar 09 '15 at 09:26
  • 1
    this old thing was like this for more than those reasons, back then programs written in 100% assembler were quite common, and many api functions were made either to be more easily compatible or were written in assembler themselves. a lot of those calls were written a really, (really) long time ago back when using classes and (what we call today) "minimal C++" was considered bloated code. These days, how many people do you think write using 100% assembler ......? (**you hear the sound of crickets**) – osirisgothra Apr 23 '15 at 03:32
  • I cannot think of a worse example. Just because it exists, it does not make it great. I've had to deal with that API before. We are stuck with it because of historical reasons and widespread usage. But under no circumstances one should see this an an example that the "right" number of parameters is somehow "context-sensitive" (it isn't.) This is akin to a natural language with nothing but simple sentences and no conjunctions of any type whatsoever. This API snippet is the closest thing to that. – luis.espinal Oct 13 '17 at 18:21
  • 1
    @luis.espinal: I think you have misinterpreted what I was trying to say, there is no "right" number of parameters, or range of parameters. If a function needs X parameters to do its job then it needs X parameters regardless of the value of X, there is no right or wrong number of parameters and it isn't something to worry about most of the time. This answer is now over 9 years old, and the example from an API even older, programming languages have come on in that time but the basic idea is the same, the idea of "too many" is not helpful. – Skizz Oct 15 '17 at 23:26
  • I see, I perhaps was too quick to judge your answer. I see your point. – luis.espinal Oct 16 '17 at 13:46
106

In Clean Code, Robert C. Martin devoted four pages to the subject. Here's the gist:

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.

Patrick McElhaney
  • 57,901
  • 40
  • 134
  • 167
  • Does that absolute upper limit of 3 include or exclude "this" in OO languages? – Steve Jessop Nov 24 '08 at 13:00
  • 2
    I doubt it includes "this" because that is the context of execution. In functional programming, the context is global and in oop, the context is the object on which you're applying the method. Also, if you'd include "this" in the parameter list, then it would be impossible to have 0 params (ideal). – Tom Nov 24 '08 at 13:07
  • 1
    No, it doesn't include "this." – Patrick McElhaney Nov 24 '08 at 21:50
  • 20
    Furthermore, Martin should have a word with the C++ standard committee. Half of takes more than 3 parameters, because just one iterator range is 2 already. It's just the nature of programming with iterators (i.e. generic programming with STL collections). – Steve Jessop Nov 27 '08 at 13:49
  • 3
    @SteveJessop: the fault of is that it always work on a slice. If algorithm and collection were to be redesigned, I would make algorithms always take a whole collection, and you'd get a way to slice a view of a collection to allow algorithms to work on parts; alternatively I'd also define a shorthand override to make it easy to work on the common case. – Lie Ryan Aug 14 '13 at 06:31
  • 3
    @LieRyan: whereas if I were redesigning `` I'd have it act on a range object. Collections would be ranges, but not all ranges would be collections. And indeed, boost has done that already. Anyway, my point is that a massively widely used library ignores this advice, so the worst that's *guaranteed* to happen to you if you do too, is that many of your millions of users will tinker with minor simplifications to your interface ;-) – Steve Jessop Aug 14 '13 at 14:36
  • This rule makes perfect sense since all the object's methods have access to all private variables. However what about constructor? If this rule does apply to constructors as well, then how are we supposed to constructor-inject more than 2-3 dependencies? Any thoughts on this? – Milos Mrdovic Sep 05 '16 at 15:04
  • 1
    @MilosMrdovic Maybe the object is doing too much by itself? Can you take 2-3 parameters, use them to construct a more specialized object, and pass that object to the constructor? – Patrick McElhaney Sep 05 '16 at 16:10
  • 1
    It's just a guideline. Sometimes you look at code and think, "I know this could be better, but I don't know how to make it better right now." So you leave it and move on. There will always be opportunities to improve. You're never going to get it perfect. – Patrick McElhaney Sep 05 '16 at 16:14
  • 1
    In some languages ppl will just pass an array to avoid too many parameters. I think this is far worse in many circumstances than too many arguments. – alvinc Nov 16 '16 at 15:06
  • @alvinc Do you mean they pass an array as the first (and only) argument? Or something like the spread operator in JavaScript? – Patrick McElhaney Nov 16 '16 at 15:53
  • @PatrickMcElhaney Yes I was referring to passing an array as the only argument, not the JavaScript spread operator. You end up searching through the documentation and/or the code itself to try and figure out what the arguments are. I much prefer the builder pattern myself. – alvinc Nov 16 '16 at 16:25
  • 1
    @alvinc Yeah, there are always going to be don't try to understand the reasoning behind a guideline, take it literally, and end up making a bigger mess. I recently ran across some code that was a series of incomprehensible nested switch / case blocks because apparently that made the cyclomatic complexity less than if they had used if statements. – Patrick McElhaney Nov 17 '16 at 21:01
  • Passing an array is a horrible thing. Better to pass an object that self-evidently packs the necessary information (and if the object is large enough,then there is no much different from passing an obscene number of parameters.) Large numbers of arguments? Arrays? Fat objects? They are all code smells hinting to bad coupling or lack of a sufficient abstraction IMO. Not always, but most of the time. – luis.espinal Oct 13 '17 at 18:24
79

Some code I've worked with in the past used global variables just to avoid passing too many parameters around.

Please don't do that!

(Usually.)

Jeffrey L Whitledge
  • 58,241
  • 9
  • 71
  • 99
  • Some code I was working on used class members to achieve the same thing. At that time I was a C programmer and I asked, why are there so many global variables, why can't input/outputs be explicitly parameters? – user3528438 Feb 02 '15 at 21:32
38

If you start having to mentally count off the parameters in the signature and match them to the call, then it is time to refactor!

Rob Walker
  • 46,588
  • 15
  • 99
  • 136
  • That is a very good answer. If the parameters are organized logically (x,y,w,h) it is easy to remember all of them in correct order. It is mutch harder to rember where to put the FILE pointer in putc (which only has two parameters), especially since fprintf is the opposite. – user877329 May 29 '16 at 10:06
  • Nicest answer. Very well said – Anwar Feb 18 '17 at 10:41
31

Thank you very much for all your answers:

  • It was a bit surprising to find people who also think (like I do) that 5 parameters is a good limit for the sanity of the code.

  • Generally, people tend to agree that a limit between 3 and 4 is good rule of thumb. This is reasonable as people usually have a bad time counting more than 4 things.

  • As Milan points, on average people can keep more or less 7 things in their head at a time. But I think that you can't forget that, when you are designing/maintaining/studying a routine, you have to keep in mind more things than just the parameters.

  • Some people consider that a routine should have as many arguments as it needs to. I agree, but only for a few specific cases (calls to OS APIs, routines where optimization is important, etc). I suggest to hide the complexity of these routines by adding a layer of abstraction just above these calls whenever possible.

  • Nick has some interesting thoughts on this. If you don't want to read his comments, I summarize for you: in a nutshell, it depends:

    I hate making hard and fast rules like this because the answer changes not only depending on the size and scope of your project, but I think it changes even down to the module level. Depending on what your method is doing, or what the class is supposed to represent, it's quite possible that 2 arguments is too many and is a symptom of too much coupling.

    The moral here is don't be afraid of showing your code to your peers, discuss with them and try to "identify areas where you have low cohesion and tight coupling".

  • Finally, I think wnoise much agrees with Nick, and concludes his satirical contribution with this poetical vision (see comments below) of the art of programming:

    Programming is not engineering. Organization of code is an art because it depends on human factors, which depend too much on context for any hard rule.

Community
  • 1
  • 1
Auron
  • 13,626
  • 15
  • 47
  • 54
16

This answer assumes an OO language. If you're not using one--skip this answer (this is not quite a language-agnostic answer in other words.

If you are passing more than 3 or so parameters (especially intrinsic types/objects), it's not that it's "Too many" but that you may be missing a chance to create a new object.

Look for groups of parameters that get passed into more than one method--even a group passed into two methods almost guarantees that you should have a new object there.

Then you refactor functionality into your new object and you wouldn't believe how much it helps both your code and your understanding of OO programming.

Bill K
  • 62,186
  • 18
  • 105
  • 157
  • Please, name a language that doesn't use routines nor parameters. I can't think of one, even assembly could be considered to have routines (labels). – Auron Oct 06 '08 at 16:36
  • x86 assembly definitely has routines (call/return). Others may require cmp/jmp combos. – Brian Knoblauch Oct 06 '08 at 16:40
  • Sorry, "ret", not "return". Sighs. It's been a long day already. – Brian Knoblauch Oct 06 '08 at 16:42
  • Sorry about the ambiguous phrasing Auron, I believe I fixed it. It was my answer that was language-specific, not the question. – Bill K Oct 06 '08 at 16:44
  • Using an OO language is irrelevant. The object can be a structure, likewise the function parameters can be constructor parameters... –  Oct 24 '09 at 10:09
  • 1
    Not all languages allow passing structures. Also, passing a structure means that the receiving method has to have the code to handle the structure and may, therefore, need more parameters. Also, in a non-oo language, you generally need an extra parameter--all OO languages have a "Hidden" parameter of "this" that should otherwise be passed in (or, in a more horrific language/design, might be globally accessible) – Bill K Oct 27 '09 at 18:38
13

It seems like there are other considerations than mere number, here are some that come to mind:

  1. logical relation to the primary purpose of the function vs. one-off settings

  2. If they are just environment flags, bundling can be very handy

John Mulder
  • 9,765
  • 7
  • 33
  • 37
12

One of Alan Perlis's well-known programming epigrams (recounted in ACM SIGPLAN Notices 17(9), September, 1982) states that "If you have a procedure with 10 parameters, you probably missed some."

Peter S. Housel
  • 2,651
  • 1
  • 22
  • 25
11

According to Steve McConnell in Code Complete, you should

Limit the number of a routine's parameters to about seven

Paul Reiners
  • 8,576
  • 33
  • 117
  • 202
9

For me , when the list crosses one line on my IDE, then it's one parameter too many. I want to see all the parameters in one line without breaking eye contact. But that's just my personal preference.

Learning
  • 8,029
  • 3
  • 35
  • 46
  • This is good until you with with some devs would will try foo(int a, float b, string c, double d). Best to try to avoid working with them I guess. :D – Rontologist Oct 06 '08 at 16:27
  • 4
    If someone else has given classes ridiculously long names I wouldn't let that influence how I define or call my routines. – finnw Oct 06 '08 at 17:05
  • 9
    May I introduce you to the "carriage return" ? –  Oct 24 '09 at 10:10
  • 3
    When the list crosses one line on your IDE, then your monitor is too small to use it with that code and you should clearly buy a monitor with a higher horizontal resolution. A line break or a reduction of the smount of parameters are just workarounds that don't solve the root problem which is that your monitor is too small for that codebase! – Kaiserludi Aug 28 '15 at 11:27
9

I generally agree with 5, however, if there is a situation where I need more and it's the clearest way to solve the problem, then I would use more.

Inisheer
  • 20,376
  • 9
  • 50
  • 82
8

Seven things in short term memory?

  1. Name of the function
  2. Return value of the function
  3. Purpose of the function
  4. Parameter 1
  5. Parameter 2
  6. Parameter 3
  7. Parameter 4
Mike Clark
  • 10,027
  • 3
  • 40
  • 54
  • Well. It's a rule of thumb. When you are coding the body of a function, you don't care about its name, and the return value and its purporse are closely related. – Auron Dec 18 '10 at 19:23
  • 7
    8. order of parameters – Eva Oct 26 '13 at 04:00
7

In Worst 5 Code Snippets, check the second one, "Is this a constructor". It has like over 37 ⋅ 4 ≈ 150 parameters:

Here a programmer wrote this constructor [... S]ome of you may think yes its a big constructor but he used eclipse automatic code generation tools[.] NOO, in this constructor there was a tiny bug that I discovered, which made me conclude that this constructor was written by hand. (by the way this is only the top part of the constructor, its not complete).

constructor with over 150 parameters

Community
  • 1
  • 1
mohdajami
  • 9,604
  • 3
  • 32
  • 53
  • This is so sad... Not knowing about "records" or "structs" or "value objects", which bundle several values together and give them a common name so you can hierarchically represent lots of them in a readable manner is like walking around with shoes unlaced for years because nobody ever told you you could even do that – yeoman Sep 03 '17 at 06:57
6

One more than necessary. I don't mean to be glib, but there are some functions that necessarily need quite a few options. For example:

void *
mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset);

There are 6 arguments, and every one of them is essential. Furthermore, there's no common link between them to justify bundling them. Maybe you could define "struct mmapargs", but that would worse.

Kirk Strauser
  • 30,189
  • 5
  • 49
  • 65
  • Well, `prot` and `flags` could have been rolled together if it was felt by the designer that 5 was somehow a magic number that's much better than 6. A bit like the way that `open` combines the read/write mode with all the other miscellaneous flags. And maybe you *could* get rid of `offset` by specifying that the mapped section starts at the current seek position of `filedes`. I don't know if there are any situations where you can `mmap` a region that you are not capable of `lseek`ing to, but if not then it isn't strictly necessary. – Steve Jessop Aug 17 '13 at 10:47
  • ... so I think `mmap` is a good illustration of the fact that some designers and users prefer a great long list of parameters, whereas others prefer to go through a few steps preparing a smaller number of parameters before making the call. – Steve Jessop Aug 17 '13 at 10:49
  • 1
    @Steve: Setting the seek position with a separate call beforehand would have introduced a gratuitous race condition. For some APIs (OpenGL), there are so many parameters that affect a call that you really have to use state, but normally, every call should stand alone as much as possible. Action at a distance is the path to the dark side. – Ben Voigt Sep 26 '15 at 16:15
5

According to Perl Best Practices, 3 is okay, 4 is too many. It's just a guideline, but in our shop that's what we try to stick to.

Adam Bellaire
  • 108,003
  • 19
  • 148
  • 163
5

I'd draw the limit for public functions at 5 parameters myself.

IMHO, long parameter lists are only acceptable in private/local helper functions that are only meant to be called from a few specific places in the code. In those cases, you may need to pass a lot of state information along, but readability isn't as big of a concern since only you (or someone who will maintain your code and should understand the fundamentals of your module) have to care about calling that function.

Kip
  • 107,154
  • 87
  • 232
  • 265
  • Which exactly why lots of people at this point would make everything that is not an actual argument, but state carried around, just state of an object in the form of fields (member variables). That object would be represented as a class. It would be instantiated either once or for every use. Sometimes such an object will only have one package private or public method, which then delegates work to private methods with few arguments each. Few arguments are now possible because configuration and state now have a proper place :) – yeoman Sep 03 '17 at 06:40
5

A related question you should be considering is how cohesive the routine is. A large number of parameters may be a smell that's telling you that the routine itself is trying to do too much and hence it's cohesion is suspect. I agree that a hard and fast number of parameters is probably impossible but I would guess that a high cohesion routine would imply a low number of parameters.

Onorio Catenacci
  • 14,928
  • 14
  • 81
  • 132
5

97 sounds just about right.

Any less and you lose flexibility.

Community
  • 1
  • 1
Johan
  • 74,508
  • 24
  • 191
  • 319
4

I stop at three parameters as a general rule of thumb. Any more and it's time to pass an array of parameters or a configuration object instead, which also allows for future parameters to be added without changing the API.

Eran Galperin
  • 86,251
  • 24
  • 115
  • 132
  • If the API changes, then the API should actually change, not just have a stealth change where the incompatibility might still happen, but be less obvious. – wnoise Oct 06 '08 at 16:29
  • however, if you need one more parameter for configuring an edge case, it shouldn't propagate to non related components using the API – Eran Galperin Oct 06 '08 at 16:35
4

A length restriction on a parameter list is just one more restriction. And restriction means applied violence. It sounds funny, but you can be non-violent even when programming. Just let the code dictate the rules. It is obvious that if you have many parameters, the body of the function/class method will be big enough to make use of them. And big code snippets usually can be refactored and split into smaller chunks. So you get solution against having many parameters as free bonus, since they are split among the smaller refactored pieces of code.

Anonymous
  • 265
  • 3
  • 7
4

One thing I would point out from a performance perspective is that depending on how you pass parameters to a method, passing lots of parameters by value will slow the program down because each parameter has to be copied and then placed on the stack.

Using a single class to encompass all of the parameters would work better because a single parameter passed by reference would be elegant and cleaner, and quicker!

Dominic Zukiewicz
  • 8,258
  • 8
  • 43
  • 61
  • I am giving this answer a +1 because its the only one that discusses anything besides code-cleanliness or arbitrary limits, which are both subjective. Some people might not think about what you're doing to the stack when you're in a loop and pushing dozens of arguments on and off the stack. If it's in a loop, you should consider using the number of arguments that are passed by REGISTERS in the ABI you're compiling for. For example, in the MS x64 ABI, the max args passed thru registers is 4. The "System V" ABI (used by non-Windows OS) uses more registers, so using 4 args pretty portable – Lakey Feb 13 '13 at 05:07
3

My rule of thumb is that I need to be able to remember the parameters long enough to look at a call and tell what it does. So if I can't look at the method and then flip over to a call of a method and remember which parameter does what then there are too many.

For me that equates to about 5, but I'm not that bright. Your mileage may vary.

You can create an object with properties to hold the parameters and pass that in if you exceed whatever limit you set. See Martin Fowler's Refactoring book and the chapter on making method calls simpler.

Mike Two
  • 44,935
  • 9
  • 80
  • 96
3

According to me there could be cases where you will exceed 4 or some fixed number. Things to lookout could be

  1. Your Method is doing too much and you need to refactor.
  2. You might want to consider using a collection or some data structure.
  3. Rethink your class design, maybe some things do not need to be passed around.

From an angle of ease of use or ease of reading code, I think when you need to kinda "word wrap" your method signature, that should make you stop and think,Unless you feel helpless and all efforts of making the signature smaller lead to no result. Some very good libraries in past and present use more than 4-5 prams.

Perpetualcoder
  • 13,501
  • 9
  • 64
  • 99
1

I agree with Robert Martin's quote in Clean Code (as cited above): the fewer parameters the better. More than 5-7 parameters and method calls become pretty hard to comprehend. Things get especially bad if some of the parameters are optional (and so take null values), or if all the parameters have the same type (making it even harder to figure out which parameter is which). If you can bundle parameters into cohesive domain objects like Customer and Account, your code will be much more pleasant to work with.

There is an edge case: if you have a method call that takes a variable number of parameters which form a logical set, there's less cognitive overhead having more parameters. For example you may need a method that specifies a number of HTTP request retries, in terms of the number of milliseconds between retries. Three retries at 1s, 2s, and 3s intervals could be specified as:

retries(1000, 2000, 3000)

In this limited case, adding more parameters to a call doesn't increase the mental overload that much.

Another consideration is if your language supports named parameter lists and allows you to leave out optional parameters. Larger named parameter lists are easier to comprehend than larger unnamed parameter lists.

But I'd still err on the side of fewer rather than more parameters.

Community
  • 1
  • 1
Jim Ferrans
  • 30,582
  • 12
  • 56
  • 83
1

It heavily depends on the environment you're working in. Take for example javascript. In javascript the best way to pass in parameters is using objects with key/value pairs, which in practice means you only have one parameter. In other systems the sweet spot will be at three or four.

In the end, it all boils down to personal taste.

Joeri Sebrechts
  • 11,012
  • 3
  • 35
  • 50
1

I'll agree with 3 is okay, 4 is too many as a guideline. With more then 3 parameters, you are inevitably doing more then one task. More then one tasks should be split into separate methods.

However, if I looked at the latest project I've worked on, the exceptions would abound and most cases would be hard to get down to 3 parameters.

kae
  • 733
  • 1
  • 6
  • 8
1

If I have 7-10 parameters in one routine I look at bundling them into a new class but not if that class would be nothing but a bunch of fields with getters and setters - the new class has to do something other than shuffle values in and out. Otherwise I'd rather put up with the long parameter list.

finnw
  • 47,861
  • 24
  • 143
  • 221
  • 1
    I will bundle it with a data-only class if it is used in more than one place, but even then I usually create both constructors. – Leahn Novash Jul 03 '09 at 16:51
1

It's a known fact that, on average, people can keep 7 +/- 2 things in their head at a time. I like to use that principle with parameters. Assuming that programmers are all above-average intelligent people, I'd say everything 10+ is too many.

BTW, if parameters are similar in any way, I'd put them in a vector or list rather than a struct or class.

Milan Babuškov
  • 59,775
  • 49
  • 126
  • 179
1

I would base my answer on how often the function is called.

If it is an init function that is only ever called once then let it take 10 parms or more, who cares.

If it is called a bunch of times per frame then I tend to make a structure and just pass a pointer to it since that tends to be faster ( assuming that you are not rebuilding the struct every time as well ).

KPexEA
  • 16,560
  • 16
  • 61
  • 78
1

According to Jeff Bezos of Amazon fame, no more than can be fed with two pizzas:

Kevin Pang
  • 41,172
  • 38
  • 121
  • 173
0

I'd say as long as you have overloads that have 2-4 than you're good to go up higher if you need it.

Chad Moran
  • 12,834
  • 2
  • 50
  • 72
0

I think the actual number really depends on what makes logical sense with the context of the function. I agree that around 4-5 parameters starts getting crowded.

In the case of setting flags, a great way to handle this situation is to enumerate the values and OR them together.

Jordan Parmer
  • 36,042
  • 30
  • 97
  • 119
0

IMO, the justification for a long param list is that the data or context is dynamic in nature, think of printf(); a good example of using varargs. A better way to handle such cases is by passing a stream or xml structure, this again minimises the number of parameters.

A machine surely wouldn't mind a large number of arguments, but developers do, also think of the maintenance overhead, the number of unit test cases and validation checks. Designers also hate lengthy args list, more arguments mean more changes to interface definitions, whenever a change is to be done. The questions about the coupling/cohesion spring from above aspects.

questzen
  • 3,260
  • 18
  • 21
  • You crazy, man? A xml structure? For parameter passing? What do you have so much against using arrays that you must go through the whole overhead of writing the xml, and then parsing it 5 cpu cycles after? – Leahn Novash Jul 03 '09 at 16:49