I needed to add a logger into my flow based on FluentIterable from the Guava library. I have a lot of functions and in some cases I would like to add logging when in other cases (for the same function) I would not.
Of course the natural solution for this problem is to use the decorator pattern, so I created something like this:
/**
* Decorator function that add logging into function passed as parameter.
*
* @param <I> input type
* @param <O> output type.
*/
public class DecoratorLoggerInfoFunc<I, O> implements Function<I, O> {
/**
* Original function
*/
private final Function<I, O> function;
/**
* Current logger.
*/
private final Logger logger;
/**
* "Builder" that takes function and return function decorated by logger.
*
* @param function function to decorate.
* @param <I> input type
* @param <O> output type
* @return function with logger.
*/
public static <I, O> Function<I, O> of(Function<I, O> function) {
checkNotNull(function, "Function to decorate cannot be null");
return new DecoratorLoggerInfoFunc<I, O>(function);
}
/**
* Initialize logger!
*
* @param function original function.
*/
private DecoratorLoggerInfoFunc(Function<I, O> function) {
this.function = function;
this.logger = LoggerFactory.getLogger(function.getClass());
}
/**
* Flow:
* <ul>
* <li>Call original function</li>
* <li>Log input and output</li>
* <li>Return output of original function</li>
* </ul>
*
* @param input
* @return
*/
@Override
public O apply(I input) {
O output = function.apply(input);
logger.info("Input is {} Output is {}", input, output);
return output;
}
}
Is this code a good way to solve my problem? Is there a better way to do this?