Reputation: 10604
I have the following code blocks on several places in one class:
final Key key = ...;
return CompletableFuture.supplyAsync(
() -> FooDelegate.call(key, () -> {
return doSomething();
}
}...
I want to adapt TO Supplier
(needed for supplyAsync()
) FROM custom Callable
code block. Method FooDelegate.call()
wraps the real code-block (here it is just doSomething()
, provided as lambda) - and we need to pass more then one arguments, like the key
(i.e. FooDelegate
is not going to be a functional interface).
Code for FooDelegate
, a separate class, since it needs to be reused:
public class FooDelegate {
public static <T> T call(Key key, Callable<T> callable) {
try {
return callable.call();
}
catch (ExecutionException e) {
...
}
... handle exceptions etc.
}
}
My questions:
Is there better way to do this: ...() -> FooDelegate.call(key, () -> {...
FooDelegate
is just a dummy class with single static method. Not sure if I like that. Anything better?
Upvotes: 0
Views: 2149
Reputation: 298123
There is nothing wrong with classes providing static
methods (or even a single static
method). I’m not sure what you actually want to do, especially as the need for additional parameters is not clear but let’s suppose you are using it somewhere in the exception handling code and treating everything else as you have written, I guess what you actually want to do is:
public class FooDelegate {
public static <T> Supplier<T> call(Key key, Callable<T> callable) {
return () -> {
try {
return callable.call();
}
catch(ExecutionException e) {
//...
throw new RuntimeException(); // or return fall-back
}
catch(Exception ex) {
//... handle exceptions etc.
throw new RuntimeException(); // or return fall-back
}
};
}
}
with the use case:
final Key key = null;//...;
return CompletableFuture.supplyAsync(FooDelegate.call( key, () -> doSomething() ));
which can be simplified to
final Key key = null;//...;
return CompletableFuture.supplyAsync(FooDelegate.call(key, MyClass::doSomething ));
or
final Key key = null;//...;
return CompletableFuture.supplyAsync(FooDelegate.call(key, this::doSomething ));
depending on whether doSomething
is a static
or an instance method…
If you need your original method for other use cases you may consider providing two methods:
public class FooDelegate {
public static <T> Supplier<T> supplier(Key key, Callable<T> callable) {
return () -> call(key, callable);
}
public static <T> T call(Key key, Callable<T> callable) {
try {
return callable.call();
}
catch(ExecutionException e) {
//...
throw new RuntimeException(); // or return fall-back
}
catch(Exception ex) {
//... handle exceptions etc.
throw new RuntimeException(); // or return fall-back
}
}
}
and change the use site to
final Key key = null;//...;
return CompletableFuture.supplyAsync(FooDelegate.supplier(key, () -> doSomething() ));
etc.
Upvotes: 1