5

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

2
  • 6
    As the saying goes: if you have a function taking 10 parameters, you probably forgot a few. Sep 12, 2012 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. Sep 12, 2012 at 16:16

2 Answers 2

8

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(...).

2
  • very good answer, +1 to split functionality in methods as basic as possible
    – marktani
    Sep 12, 2012 at 16:31
  • 5
    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, 2012 at 18:49
7

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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