tags:

views:

75

answers:

6

When I try to refactor my functions, for new needs, I stumble from time to time about the crucial question: shall I add an other variable with a default value? Or shall I user only one array, where I´m able to add an additional variable without breaking the API?

+1  A: 

Unless you need to support a flexible number of variables, I think it's best to explicitly identify each parameter. In most cases you can add an overloaded method that has a different signature to support the extra parameter while still supporting the original method signature. If you use an array for passing variables it just makes it too confusing for users of your API. Obviously there are some inputs that lend themselves to an array (a list of points in a polygon, a list of account IDs you wish to perform an action on, etc.) but if it's not a variable that you would reasonably expect to be an array or list, you should pass it into the method as a separate parameter.

TLiebe
A: 

It depends on the programming language used.

If you have a run-of-the-mill OO language, you should use an object that you can easily extend, if you are really concerned about API consistency.

If that doesn't matter that much, there is the option of changing the method signature and overloading the method with more / different parameters.

If your language doesn't support either and you want the API to be binary stable, use an array.

Gerd Klima
A: 

There are several considerations that must be made.

  • Where is the function used? - Only in code you created? One place or hundreds of places? The amount of work that will need to be done to maintain existing code is important. Remember to include the amount of time it will take to communicate to other programmers that may currently be using your function.
  • How critical is the new parameter? - Do you want to require it to be used? If it has a default value, will that default value break existing use of the function in any subtle ways?
  • Ease of comprehension - How many parameters are already passed into the function? The larger the number, the more confusing and error prone it will be. Code Complete recommends that you restrict the number of parameters to 7 or less. If you need more than that, you should try to abstract some or all of the related parameters into one object.
  • Other special considerations - Do you want to optimize your efforts for any special conditions such as code speed or size? Are there any special considerations that must be taken into account for your execution environment? Keep in mind your goals for the project and make sure you aren't working against them with whatever design choice you make.
Ben Gartner
If I shouldn´t give more than 7 parameters to a function, what´s with a database function with, let´s say 10 ore more rows? I have to give all the parameters to the function, dont´I?
MaikL80
The guideline is there to allow you to design functions that reduce confusion by reducing complexity. This doesn't guarantee that you will always be using functions that followed the same principles. Definitely pass more than 7 parameters to a function if someone else wrote it and you need the function.If many of the parameters are going unused, or being set to some default values, consider wrapping the function in another function that allows you to hide these details. That way you can think about it in just one place and reduce complexity elsewhere.
Ben Gartner
Ok, I see. But the main question stays for me. How can I manage to write a database insert/update function with more than 7 values? Please don´t say, that I should normalize the database, it is already done quite well (I think). But in some cases you have a bunch of content, that you want to give to the database function. You see my problem?
MaikL80
The guideline is from 7.5 of Code Complete second edition (page 178.) The explanation is that psychological research has shown that people start getting confused when they have to think about more than 7 things simultaneously. McConnell suggests either dividing the routine into multiple routines, or grouping some of the related parameters into their own classes or structs. I would recommend the latter approach: look for related parameters and put them in a single struct, or create a new class that contains the data. Repeat this process into you have about 5 or fewer individual parameters.
Ben Gartner
+1  A: 

Just like many questions in programming, the right answer is "it depends".

To take Javascript/jQuery as an example, one good rule of thumb is whether the parameter will be required each time the function is called or whether it is optional. For example, the main jQuery function itself requires an expression to determine what element(s) the operation will affect:

jQuery(expresssion)

It makes no sense to try to pass this parameter as part of an array as it will be required every time this function is called.

On the other hand, many jQuery plugins require several miscellaneous parameters that may be optional. By convention, these are passed as parameters via an 'options' array. As you said, this provides a nice interface as new parameters can be added without affecting the existing API. This makes the API clean as well since the user can ignore those options that are not applicable.

In general, when several parameters are involved, passing them as an array is a nice convention as many of them are certainly going to be optional. This would have helped clean up many WIN32 API's, although it is more difficult to deal with arrays in C/C++ than in Javascript.

Justin Ethier
A: 

In his book Code Complete, Steve McConnell decrees that a function should never have more than 7 arguments, and rarely even that many. He presents compelling arguments - that I can't cite from memory, alas.

Clean Code, more recently, advocates even fewer arguments.

So unless the number of things to pass is really small, they should be passed in an enveloping structure. If they're homogenous, an array. If not, then a reasonably lightweight object should be built for the purpose.

Carl Smotricz
A: 

You should do neither. Just add the parameter and change all callers to supply the proper default value. The reason is that parameters with default values can only be at the end, and will not be able to add any more required parameters anywhere in the parameters list, without having a risk of misinterpretation.

These are the critical steps to disaster: 1. add one or two parameters with defaults 2. some callers will supply it, and some will rely on defaults. [half a year passed] 3. add a required parameter (before them) 4. change all callers to accept the required parameter 5. get a phone call, or other event which will make you forget to change one of the instances in part#2 6. now your program compiles perfectly, but is invalid.

Unfortunately, in function call semantics we usually don't have a chance to say, by name, which value goes where.

Array is also not a proper solution. Array should be used as a connection of similar objects, upon which there's a uniform activity performed. As they say here, if it's worth refactoring, it's worth refactoring now.

Pavel Radzivilovsky