I have a method that takes 30 parameters. I took the parameters and put them into one class, so that I could just pass one parameter (the class) into the method. Is it perfectly fine in the case of refactoring to pass in an object that encapsulates all the parameters even if that is all it contains.
-
The answers below are good. I always set up a class for this purpose. Are you using Automatic properties? http://msdn.microsoft.com/en-us/library/bb384054.aspx – Harv Nov 10 '11 at 17:10
-
Otherwise known as a POD (plain-old-data) type. – new123456 Nov 10 '11 at 21:41
-
17While many of the answers given are great, and it is indeed a good idea to refactor those parameters into something a little easier to handle, I would say that the fact that this method needs 30 distinct pieces of data to do its thing is a sign that it's doing too much. But then again, we haven't seen the method in question, or even know of its purpose. – user Nov 11 '11 at 09:20
-
1So that method that took all the parameters, did you move it into the new class? Or does the old method just take the new class as its single parameter? I would look at putting the method in the new class, if it makes sense. Classes with only data and no methods are called anemic classes, and it feels a bit less OO. Not a hard and fast rule though, just something to look at. – Kurt Nov 15 '11 at 17:17
-
@Michael: I agree with you. Another point - I believe you should not create method dedicated object unless its internal have sort of relation outside the method. – Roi Shabtai Nov 16 '11 at 13:29
-
@Kurt - I have decided to pass in an object instead of 30 parameters and then I am also investigating if the method has one more than one responsibility so I can break up the method into smaller pieces. Part of the problem also is the fact that the stored procs also contain a lot of business logic (Procs calling Procs, Functions calling Functions). – Xaisoft Nov 16 '11 at 14:29
12 Answers
That is a great idea. It is typically how data contracts are done in WCF for example.
One advantage of this model is that if you add a new parameter, the consumer of the class doesn't need to change just to add the parameter.
As David Heffernan mentions, it can help self document the code:
FrobRequest frobRequest = new FrobRequest
{
FrobTarget = "Joe",
Url = new Uri("http://example.com"),
Count = 42,
};
FrobResult frobResult = Frob(frobRequest);

- 12,334
- 7
- 53
- 76
-
Great. I was under the impression that just having a class with properties and no methods was useless. – Xaisoft Nov 10 '11 at 17:03
-
2If it will contain only data members, I prefer to make it struct. Using struct gives the impression that it is just data. – Yousf Nov 11 '11 at 09:48
-
28using struct has side effects like copy on passing semantics. Please make sure you are aware of that before making such a decision – Adrian Zanescu Nov 11 '11 at 12:40
-
This is how javascript modules are usually written, and it seems to be the best method for accepting more or less params as the module matures. someFunction({ myParam1: 'something', myParam2: 'somethingElse' }); – Kristian May 14 '12 at 15:30
While other answers here are correctly point out that passing an instance of a class is better than passing 30 parameters, be aware that a large number of parameters may be a symptom of an underlying issue.
E.g., many times static methods grow in their number of parameters, because they should have been instance methods all along, and you are passing a lot of info that could more easily be maintained in an instance of that class.
Alternatively, look for ways to group the parameters into objects of a higher abstraction level. Dumping a bunch of unrelated parameters into a single class is a last resort IMO.
See How many parameters are too many? for some more ideas on this.

- 1
- 1

- 167,292
- 40
- 290
- 283
-
In what sense are these parameters unrelated? They are all used by this method. That's a very strong relationship. What's more, parameters on the stack are generally preferable to state. Think about multi-threading. – David Heffernan Nov 10 '11 at 17:24
-
12That can't be answered without seeing the OP's code, but I disagree that simply because two values are used together in a method, they have a strong relationship. If that were true, OO design would end up meaning creating one big class that holds every possible property used in your application. – D'Arcy Rittich Nov 10 '11 at 17:33
-
No you are right, not necessarily related. But also not necessarily unrelated. So, as you say, would need to see code to be sure. – David Heffernan Nov 10 '11 at 17:47
-
2330 parameters? I'd settle for most probably unrelated and also probably indicative of a method that is too long, has high cyclomatic complexity and is a haven for bugs. Consider that we're talking about a method whose behaviour has at least 30 dimensions in which it can vary. If there are unit tests for this method I wouldn't want to be the one to write them TBH. – Steve Rowbotham Nov 10 '11 at 18:07
-
3Another likely scenario is that all the parameters are related, but they are poorly organized. It is quite likely that groups of parameters should be bundled into distinct objects rather than passed around piecemeal. Say I have a method that operates on information like "person", "address", "prescription"... that could easily amount to 30 parameters if each of the discrete pieces of information were passed into my method separately. – Nate C-K Nov 15 '11 at 17:21
It's a good start. But now that you've got that new class, consider turning your code inside-out. Move the method which takes that class as a parameter into your new class (of course, passing an instance of the original class as the parameter). Now you've got a big method, alone in a class, and it will be easier to tease it apart into smaller, more manageable, testable methods. Some of those methods might move back to the original class, but a fair chunk will probably stay in your new class. You've moved beyond Introduce Parameter Object on to Replace Method with Method Object.
Having a method with thirty parameters is a pretty strong sign that the method is too long and too complicated. Too hard to debug, too hard to test. So you should do something about it, and Introduce Parameter Object is a fine place to start.

- 39,912
- 17
- 102
- 155
-
4This is ABSOLUTELY IMPORTANT! Creating these attribute bundles is great only because it's the first step to creating new classes with methods of their own, and you will pretty much always find methods that belong in your new classes--look for them! I think this is the most critical answer in this group, it should be near the top. – Bill K Nov 10 '11 at 22:52
Whilst refactoring to a Parameter Object isn't in itself a bad idea it shouldn't be used to hide the problem that a class that needs 30 pieces of data provided from elsewhere could still be something of a code smell. The Introduce Parameter Object refactoring should probably be regarded as a step along the way in a broader refactoring process rather than the end of that procedure.
One of the concerns that it doesn't really address is that of Feature Envy. Does the fact that the class being passed the Parameter Object is so interested in the data of another class not indicate that maybe the methods that operate on that data should be moved to where the data resides? It's really better to identify clusters of methods and data that belong together and group them into classes, thereby increasing encapsulation and making your code more flexible.
After several iterations of splitting off behaviour and the data it operates on into separate units you should find that you no longer have any classes with enormous numbers of dependencies which is always a better end result because it'll make your code more supple.

- 2,868
- 17
- 18
That is an excellent idea and a very common solution to the problem. Methods with more than 2 or 3 parameters get exponentially harder and harder to understand.
Encapsulating all this in a single class makes for much clearer code. Because your properties have names you can write self-documenting code like this:
params.height = 42;
params.width = 666;
obj.doSomething(params);
Naturally when you have a lot of parameters the alternative based on positional identication is simply horrid.
Yet another benefit is that adding extra parameters to the interface contract can be done without forcing changes at all call sites. However, this is not always as trivial as it seems. If different call sites require different values for the new parameter, then it is harder to hunt them down than with the parameter based approach. In the parameter based approach, adding a new parameter forces a change at each call site to supply the new parameter and you can let the compiler do the work of finding them all.

- 601,492
- 42
- 1,072
- 1,490
Martin Fowler calls this Introduce Parameter Object in his book Refactoring. With that citation, few would call it a bad idea.

- 49,173
- 15
- 109
- 139
-
1Yeah, but for 30 parameters, something is wrong elsewhere which has to be fixed first – manojlds Nov 16 '11 at 01:29
30 parameters is a mess. I think it's way prettier to have a class with the properties. You could even create multiple "parameter classes" for groups of parameters that fit in the same category.

- 25,996
- 2
- 58
- 72
You could also consider using a structure instead of a class.
But what you're trying to do is very common and a great idea!

- 6,625
- 1
- 29
- 64
-
I actually thought about using a struct, but I was curious if there would be any disadvantages if I use a struct. – Xaisoft Nov 10 '11 at 17:06
-
Why David? What does the number of fields have to do with it? Just curious. – Tad Donaghe Nov 10 '11 at 17:14
-
2As a performance matter. While semantically it makes more sense to use a struct here as only the value of each field matters and reference identity is irrelevant, 30 or so fields is more to copy (say they're mostly reference types; 120bytes on 32-bit and 240bytes on 64) than with a class (4 or 8 bytes). However, the copy-by-value nature of structs means that once copied over the access is going to be faster than with a reference type, so the threshold where struct is less efficient is higher than the 1-pointer-size the above entails. At > 4 pointer-sizes its time to consider it. – Jon Hanna Nov 10 '11 at 18:53
It can be reasonable to use a Plain Old Data class whether you're refactoring or not. I'm curious as to why you thought it might not be.

- 110,372
- 10
- 146
- 251
-
I don't exactly remember,but I think when I mentioned somewhere on here a while ago that I was creating a class with just properties, it was looked down on at the time. On your second point, are you saying that only parameters that do not change should be passed in the method, in other words, if the method changes the parameter, it should not be passed in as a parameter. – Xaisoft Nov 10 '11 at 18:49
-
Classes that are only properties can be a bad smell (see Steve Rowbotham's answer) that indicate something that should be a "full" class instead. A good sign is if you end up using similar classes more than once. However, this isn't always the case, and in a toss-up between a 30-field class and a 30-parameter method, there's good call to lean to the former. Besides, it can be a start on building that "full" class. – Jon Hanna Nov 10 '11 at 19:11
-
...I'm removing my comment on immutability, as I was thinking more of the class of this being a public method only (where a "request" object describes the caller's intent). Here changing the "request" can lead to confusion. In a one-off case it's handier to be mutable and build as you go. Immutability would just mean replacing a 30-argument call with a 30-argument constructor followed by a call, so there'd be no win. – Jon Hanna Nov 10 '11 at 19:12
Maybe C# 4.0's optional and named parameters be a good alternative to this?
Anyway, the method you are describing can also be good for abstracting the programs behavior. For example you could have one standard SaveImage(ImageSaveParameters saveParams)
-function in an Interface where ImageSaveParameters
also is an interface and can have additional parameters depending on the image-format. For example JpegSaveParameters
has a Quality
-property while PngSaveParameters
has a BitDepth
-property.
This is how the save save-dialog in Paint.NET does it so it is a very real life example.

- 31
- 1
As stated before: it is the right step to do, but consider the followings too:
- your method might be too complex (you should consider dividing it into more methods, or even turn it into a separate class)
- if you create the class for the parameters, make it immutable
- if many of the parameters could be null or could have some default value, you might want to use the builder pattern for your class.

- 71
- 2
So many great answers here. I would like to add my two cents.
Parameter object is a good start. But there is more that could be done. Consider the following (ruby examples):
/1/ Instead of simply grouping all the parameters, see if there can be meaningful grouping of parameters. You might need more than one parameter object.
def display_line(startPoint, endPoint, option1, option2)
might become
def display_line(line, display_options)
/2/ Parameter object may have lesser number of properties than the original number of parameters.
def double_click?(cursor_location1, control1, cursor_location2, control2)
might become
def double_click?(first_click_info, second_click_info)
# MouseClickInfo being the parameter object type
# having cursor_location and control_at_click as properties
Such uses will help you discover possibilities of adding meaningful behavior to these parameter objects. You will find that they shake off their initial Data Class smell sooner to your comfort. :--)

- 9,984
- 5
- 45
- 53