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