11

When I have a function that might, or might not receive a certain parameter, is it better to overload the function, or to add optional args?

If each one has it's ups and downs - when would I use each?

JNF
  • 399
  • 1
  • 5
  • 17
  • Related: [Are optional parameters helpful or a hindrance to application maintenance?](http://programmers.stackexchange.com/questions/22559/are-optional-parameters-helpful-or-a-hindrance-to-application-maintenance) and [When is method overloading appropriate?](http://programmers.stackexchange.com/questions/135313/when-is-method-overloading-appropriate) – Péter Török Jun 14 '12 at 11:12
  • From the optimization perspective having optional parameters is a better option. – Maneet Puri Jun 14 '12 at 10:58

2 Answers2

13

If the language supports them properly (e.g. type-safety, if applicable), I would prefer optional arguments for the following reasons:

  • They convey your intent better so noone suspects that your function overload will do something different (which it probably shouldn't anyway).
  • Less code to maintain, even if the function overload only delegates to the more comprehensive one. If you want to rename the function later, you have at least 3 places to do it (two definitions + one call).
  • The compiler (if any) might generate smaller binaries.
  • Optional arguments scale better, at least in some languages. What if you want to have 3 optional arguments with the ability to mix and match? For full flexibility, you'd need 6 overloads to do that.
  • If it's an object method, multiple overloads will greatly hinder the implementation of overrides in subclasses.
Benjamin Kloster
  • 2,227
  • 18
  • 20
  • Wouldn't you need 8? Three optional arguments `a`, `b` and `c` has these possibilities: nothing, a, b, c, ab, ac, bc, abc. It's `2^n` for different types, not `n!` – Mark Jun 16 '18 at 14:57
0

Assuming a constructor kind of situation: I often choose a fluent builder pattern to prevent situations with many options.

Eg.Ordering.natural().onResultOf(function).reverse().compound(Ordering.natural().onResultOf(function2)) is an example of calling a fluent builder interface implemented in Guava.

Of course you now need a separate object to hold the state of your builder, but you reduce overall complexity by separating behavior of constructing from behavior of the constructed.

Dibbeke
  • 2,514
  • 1
  • 16
  • 13