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 would like to ask on method parameters design consideration. I am usually deciding between using individual variables as parameters versus grouping them to a class or dictionary as one parameter.

Is there such a rule when you should use individual parameter against using a class or a dictionary to group the parameter?

Individual parameter - Straight forward, strongly typed

Dictionary parameter - Very extensible, like HTTP request but cannot be strongly typed.

Class parameter - Extensible by adding member to the class parameter, strongly typed.

I am looking for a design reference on when to use which?

Note: I am not sure if this question is valid in programmers but I definitely think it would be closed in stackoverflow, If it is still not valid, please point me to the proper page.

share|improve this question
1  
It's a good question, and goes right to the heart of learning to understand what it is to write clean code. –  S.Robins Apr 9 '12 at 12:34

5 Answers 5

up vote 5 down vote accepted

Chapter 3 of the Clean Code book has a section in it about functions. It mentions that the ideal number of arguments is Zero, then next to ideal is One. Two if you really have to. Three should be avoided, and anything further should require special justification. This may seem similar to the answers given by both rupjones and Péter Török, however there is more to this than simply picking an arbitrary number of method parameters to deal with.

As David Wallace mentions in his answer, Readability and Maintenance are your key considerations. Every parameter you add to a method increases it's level of relative difficulty in terms of the reader's ability to understand what is going on in the method. So while a new class may be justified, the number of parameters should not be the defining reason for this. Every class you create is a new file and entity to maintain, and while this can often be the better option if it helps to keep your code clean and easy to reuse and change, this needs to be balanced against the complexity of the method and its usage of the class itself.

There are also other considerations. Your classes should only be responsible for one conceptual thing. If your method parameters are only loosely related, a class might not be justified. Your parameter list may even seem to suggest that you might need two classes, or a composite, or some other combination.

As with classes, you should also consider that your methods should only do one thing. If you have a lot of method arguments, or even if you use a large number of parameters on a class, then perhaps you're trying to do too many individual things within in a single method. You may be able to break your method down into a set of smaller methods, and in doing so reduce the clutter of parameters, and reduce the complexity of your method(s).

Waiting for your parameter list to grow before refactoring can often mean you've left a problem to be dealt with later on. It's often better to address such concerns as soon as they appear, to save you needing to deal with potentially difficult refactorings later on. Of course, if you have good test coverage, then this shouldn't be too difficult, however this should not mean you should allow yourself to become too complacent about addressing potential problems in your code as they become known to you.

So sure, there are no real hard or fast rules about this, however you'll find if you keep your methods small, and then try and find a way to make them smaller and without repetition, that many of these issues to do with the number of parameters or classes - while no less relevant - will likely appear less often.

share|improve this answer

There is no clear rule to this, it depends on a lot of things. One rule of thumb is that if the method has more than 3-5 parameters, it is advisable to group them. My first approach in such a case would always be using parameter object(s). I would use a key-value map only as a last resort, when there is a huge and/or variable number of parameters whose types are not known at compile time.

share|improve this answer

Ask yourself which approach will give you code which is the most readable, and the easiest to maintain. Code accordingly.

share|improve this answer
    
+1 Took the words right out of my mouth! ;-) –  S.Robins Apr 9 '12 at 11:41

My typical approach to this, like @peter-torok, is to group parameters if there is more than 3 (or some low value) with a class. I like to think that if it's more than this, then there's probably an important abstraction missing from your domain, in which case a class is justified.

share|improve this answer

According to Code Complete, this depends on the conceptual abstraction layer you're programming at. Software's primary technical imperative is managing complexity, so make sure you're not mixing abstractions.

For example,

public class Vechicle {
    private int id;
    private Door door;
    private Window window;
    private Trunk trunk;

    public void addDoorAndWindow(Door door, Window window) {
      // passing a vechicle object is inappropriate here, 
      // you shouldn't access the parameters with vechicle.getDoor() or vechicle.getWindow()
    } 

    public void collide(Vechicle vechicle) {
      // passing the id is inappropriate is here
      // if you need it, get it with vechicle.getId()
    }
}

You ask the question, does it make sense to pass a Vechicle to and addDoorAndWindow method. No, you're adding door and window, and not a vechicle. Does it make sense to pass an id to collide method. No, you're not collding with an id, you're colliding with a vehicle.

If you get too many individual parameters, and they are sort of related, then try introducing a Parameter Object.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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