I am re-writing some code to make functional changes and I am stuck at a situation where either I will need to overload a function to accommodate two or three types of parameters (but performing almost identical operations on them) OR use one function with a lot of parameters. Now I am going with the latter option, and I just wanted to know specific disadvantages (if any) of using a function with a lot of parameters (and when I say lot, I mean 15).
I am looking for a general answer, nothing language specific, so I am not mentioning the language here, but just for information, I am using C#.
Thanks
Rishi
The problem with a lot of parameters is that at the place where you call the code it can be difficult to see what the parameters mean:
// Uhh... what?
run(x, y, max_x, true, false, dx * 2, range_start, range_end, 0.01, true);
Some languages solve this by allowing named parameters and optional parameters with sensible defaults.
Another approach is to put your parameters in a parameter object with named members and then pass that single object as the argument to your function. This is a refactoring appraoach called Introduce Parameter Object.
You may also find it useful to put one group of related parameters that belong together into one class, and another group of parameters into a different class.
you may try to think as the one who will use the method.
The best is to have a comprehensible use of each arguments.
if all arguments are not used in all cases, you can :
- use optional parameters (c# 4 for example support that)
- use struct or class to hold parameters and only fill required properties
- refactor your code. I don't know what your code does, but it seems to my eyes a huge number of parameters
If you're trying to write your code "the functional way" you might find "Currying" useful, and create meaningful functor objects that are initialized with just a couple of parameters. If a function takes a lot of parameters, their list may (or should) usually be divided into meaningful chunks, and currying should form a chain of functions with meaningful intent.
So instead of (example of this answer):
run(x, y, max_x, true, false, dx * 2, range_start, range_end, 0.01, true);
you might use
// initialize functors
run_in_userbox = run(x, y, max_x);
run_with_bounds = run_in_userbox(true, false);
iterate_within_bounds = run_with_bounds(dx * 2, range_start, range_end, 0.01);
result = iterate(true); //computation only starts here
I don't know if C# supports this, but that's how the problem is usually solved in functional languages.
The way I normally handle this is to have very small separate methods for each signature needed, but have them call private methods to do the actual work, which as you said is pretty much identical between the use cases.