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 have a problem related to this:

Are there guidelines on how many parameters a function should accept?

In my case, I have a function that describes a rounded rectangle. The caller specifies

  • An integer which determines how the rectangle should be merged into previously created shapes
  • An Anchor, which is a point that is used for alignment (right, left, top, bottom etc). (0,-1) means that position (next parameter) describes the top, middle point of the rectangle.
  • The position of the rectangle
  • Width and height
  • Corner radius

Should I use Parameter Object pattern in this case? It is hard to see how these parameters are related

share|improve this question
6  
As the saying goes: if you have a function taking 10 parameters, you probably forgot a few. –  Joris Timmermans Sep 12 '12 at 15:45
    
The more parameters of the same type you use, the more likelihood someone will transpose them, e.g. swapping the int X and int Y coordinates. I have no idea how people control lots of parameters without type safety. Not sure what language you are using, but Java has a Point and a Point2D that can be used to avoid some confusion. –  GlenPeterson Sep 12 '12 at 16:16
add comment

2 Answers

up vote 8 down vote accepted

I prefer to keep the number of function arguments to four or fewer.

It sounds like the function "merges" a rounded rectangle it into some environment. The first thing that comes to mind is to separate the activity into two parts: defining the rectangle, and then merging it.

rr = roundedRectangle(width, height, cornerRadius)
environment.merge(rr, how, alignment, where)

If the cornerRadius has a convenient default (e.g. zero), then you could switch to:

rr = roundedRectangle(width, height).setCornerRadius(r)

If the number of options to merge increases, then you could create a parameter object for those:

mm = mergeMethod(position).setAlignment(topCenter).setBehavior(...)
env.merge(rr, mm)

This allows for a natural extension to other shapes. It would be poor practice to repeat the list of mergeMethod arguments once for every shape that could be created.

=== Dan's Addendum ===

When splitting actions in this way, it is important to avoid introducing undesirable order dependencies. Any values not specified when an instance is created should have useful defaults. If you remove the cornerRadius argument from the roundedRectangle constructor, you must set a useful default. It must be sensible to write either rr = roundedRectangle(width, height) or rr = roundedRectangle(width, height).setCornerRadius(...).

share|improve this answer
    
very good answer, +1 to split functionality in methods as basic as possible –  mcwise Sep 12 '12 at 16:31
4  
However, you do want to watch out for situations where "you have to call Y after X" because an interface can't enforce that. –  Dan Sep 12 '12 at 18:49
add comment

Not all the parameters are related, but some subsets are. You could have 3 parameters:

  • Merge behavior
  • Position (base position & anchor point)
  • Rectangle description (height, width, corner radius)

Or, it might make more sense that anchor point is part of the rectangle description.

share|improve this answer
add comment

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.