2

I'm currently defining a Function within a method to help w/ two objectives:

  1. Simplify the if block in a section of non-stream driven code,
  2. Encapsulating the function within the method for which it's only relevant.

Example (for illustration only):

public String someMethod(String parm1, String parm2) {
  final Function<String, Boolean> isValidString = parm -> parm.equals("Test") || parm.equals("Test2"); 
  ...
  String parm1 = ...
  if (parm1 != null && isValidString.apply(parm)) {
    ... do something
 }
 ...

In my situation the Function method is a bit more complex and covers 1 specific business case I'm checking for within the if block.

Is there a standard design pattern or anti-pattern for this or recommendation? I'm specifically looking for answers more than just personal preference.

===

Summarized Result:

Pro's: Encapsulation, Readability and access to final/effective final variables in scope.

Con's: Having too many or too complex of functions can create code legibility issues.

Craig Taylor
  • 1,689
  • 1
  • 11
  • 13

1 Answers1

1

This use of Function<T,R> is a pattern that stands for local method - a language feature missing in Java, but present in other programming languages.

There is absolutely nothing wrong with using this pattern, especially if you are planning to reuse the same validation logic multiple times within the same method implementation.

Unlike a private method, a local function lets you capture param1 and param2 implicitly in case you need them:

final Function<String, Boolean> isValidString = parm -> parm.equals(param1); 
//                                                                     ^
//                                                                     |
// Implicitly captured param1   ---------------------------------------+

Note: Since your function returns Boolean, a more appropriate interface for it would be Predicate<String>:

final Predicate<String> isValidString = parm -> parm.equals("Test") || parm.equals("Test2");
...
if (parm1 != null && isValidString.test(parm)) {
    ...
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I've used your term 'local method' and only been able to find C# implementing a similar concept of local functions. It's use cases as stated mirror the objectives I was trying to achieve however they failed to advise on problems with it (other than length for read-ability). Are you aware of other languages sharing a similar construct? I'd be interested in their approaches / advice on when to use or not use this construct. I'll accept your answer if you can help me find any additional insight. Thanks, – Craig Taylor Sep 21 '17 at 03:16
  • @CraigTaylor The corresponding feature in Swift is called "nested functions" ([reference](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html)). – Sergey Kalinichenko Sep 21 '17 at 03:22
  • First link searching for "nested functions swift" took me to this Stack Overflow answer: https://stackoverflow.com/questions/32968133/what-is-the-practical-use-of-nested-functions-in-swift . I'll update the question to provide a summary of pros/cons that I've seen mentioned there and in the C#. – Craig Taylor Sep 21 '17 at 03:41