When does the function (or method, if you use Java)
myFunction(param1, param2, ..., paramn)
have too many parameters?
Clearly one parameter is not too many, and clearly 16 parameters would be too many. I personally prefer to use no more than two or three parameters, but even this can be too many when all of the parameters are of the same type. For example, it is easy to inadvertently swap the parameters in a call to the function
myFunction(int param1, int param2)
unless param1 and param2 have a natural and obvious semantic order.
(removed information already covered below.)
I have found one instance where the parameter count is difficult to limit: in the constructors of ImmutableObject
s. How do I limit the parameter count (or alternatively make the ordering obvious) in the constructor of an immutable object with several fields? One approach: Build a factory. If you need immensely complex objects, allow the factory to build a component from a string-descriptor or input stream. Another approach: build a (mutable) parameter-structure that defaults to reasonable values, and pass that into the constructor.
- Use named parameters for those that are optional (if language supports them)
- Pass in an associative array or object
- Use regional (module-wide) variables (controversial)
- Use Pascal-like nested functions to manage scope
. Or program in a language that has them (Lisp, VB, ObjectiveCaml
Or you might use a ParameterObject
[Or assuming the function is a method in a class have attribute variables of the class
to pre-store some of the information needed by the function. But then you may need additional Set() functions before calling the function you are focused on. Then you have to balance against LotsOfShortMethods
When I'm looking for a short solution to this problem I usually just pass in a hash with a pre-set list of either strings or symbols as keys. But this is usually a hack, and if I end up working on that code for a while I often refactor out some sort of intermediate class. Maybe TooManyParameters is a smell. --francis
- That's usually an AntiPattern due to problems regarding incomplete initialization.
I have a config file that contains options, formula etc, and is read in by a class which stores the config in some internal efficient format. Now I need to pass in data corresponding to that config and get results out. What is the best pattern to use here? I started off with having another class that knows the interals of the above class and so is able to compute the formula for the given input - I did not like this because if I change the way I stored the config/formula I would need to change this processor class also; then I thought about having methods within the same original class for processing the input since it knows the internal representation of the config and so is in a best position to provide the output for a given input. But then as I execute several steps for producing an output, I would end up with method calls for each step, and each of those methods having too many parameters relating to the input and relating to the previous steps. One way could be to use a parameter object, but I am trying to see if there is a pattern identified for the "formula config and processing".
is often a CodeSmell
. If you have to pass that much data together, it could indicate the data is related in some way and wants to be encapsulated in its own class. Passing in a single structure data that belongs apart doesn't solve the problem. Rather, the idea is that things that belong together, keep together; things that belong apart, keep apart; per the OneResponsibilityRule
Suppose I encapsulate those input data that belong together; then what would be the best structure/pattern to do the 'evaluation' of the formula/options given a config and an encapsulated input? One option is to have several methods within the config class to be responsible for each of the evaluation steps, and a composing method that executes these steps. The other option is to have a separate evaluator class (which is cleaner, I think) but not clear how it could avoid knowning the inner representation of the config.. I am thinking of coding in Java.
As long as you use them properly, I see nothing really wrong with module-level variables. They have a bad rap, but the alternative is often uglier, forcing one to package concepts that perhaps should not be packaged over the longer run. In other words, excessive or inappropriate coupling.
See also LongParameterList