2

Today I was writing a function that had two required arguments and three optional arguments. Since using Optional<> types is frowned upon as arguments, function overloading has been my tool to handle this. So I end up with something like this:

public boolean func(int a, String b)

public boolean func(int a, String b, String c)

public boolean func(int a, String b, int d)

public boolean func(int a, String b, long e)

Then I have to do the various combinations of two arguments...

public boolean func(int a, String b, String c, int d)

public boolean func(int a, String b, String c, long e)

public boolean func(int a, String b, int d, long e)

and finally the "full function"

public boolean func(int a, String b, String c, int d, long e)

This seems like too much work to me, and when that happens I feel like im doing something wrong. Why should I be creating 7 additional functions instead of using an Optional or a POJO in this case? What is the most efficient way to handle this?

  • 1
    why cant you make it something like `public boolean func(int a, String b, Object... args)` and check the type inside – Arun Sudhakaran May 05 '18 at 16:04
  • You might want to use the varargs method mentioned in this post: https://stackoverflow.com/questions/965690/java-optional-parameters?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Stan Fieuws May 05 '18 at 16:18

1 Answers1

1

You absolutely do not have to implement all combinations of optional parameters.

The key perspective to keep in mind when making a decision over this is how useful it's going to be to the caller. If you don't have use cases to support and expose overloaded methods for, then creating those overloaded methods simply adds unnecessary code that generates needless testing and maintenance burden.

If you're looking for an easier way to expose the same flexibility, then you can use Optional:

public boolean func(int a, String b, 
   Optional<String> c, Optional<Integer> d, Optional<Long> e)

This is probably a good compromise, allowing your contract to be functionally equivalent to the initial API with many overloaded methods. It allows your clients to choose what they send, and allows you to void API clutter. Above all, it makes evident what's optional, removing the need for callers to read the documentation of each method.

ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • I thought Optionals were only for return types for use in streams? The java guys seems to be adamant about not using this pattern which is why I didn't. –  May 05 '18 at 16:06
  • @rec Now that's the choice of the API developer. Using Optional as a method parameter is understandably discouraged, but that justification is not categorical. You as the developer will assess which is better: nullable boxed primitives, a ton of method overloads, Optionals, range-based contract (such as if `c < 0`, ignore it)? Each option has its downside. **But I believe that the biggest gain will come from eliminating unnecessary overload options and implementing just the few that are really needed for the API** – ernest_k May 05 '18 at 16:21