Compondo funções em Java?
-
18-09-2019 - |
Pergunta
Estou escrevendo código de demonstração para uma API que criamos e continuo correndo no mesmo problema em que estou repetindo -me repetidamente ad nauseum. Estou dolorosamente ciente de que Java está programado para ter fechamentos adicionados, mas não tenho acesso a eles agora. Aqui está o que é repetido em todo o lugar que eu gostaria de encaixar em seu próprio canto:
public BarObj Foo(Double..._input){
try{
//things that vary per function
//but everything else...
} catch(NullException _null){
m_Logger.error("Null error exception caught in Blah::Foo");
return null;
} catch(Exception ex){
m_Logger.error( ex.getMessage() );
return null;
}
}
Sobre a única maneira de pensar em dar a volta, passando por um Method
em uma função que carrega consigo a lógica de try-capatch e envolver tudo em outra função como assim:
public BarObj MyFunc(Double..._input){
return compose("MyLogic",_input);
}
private BarObj MyLogic(Double..._input)
throws Exception{
//stuff
}
Mas parece feio e carrega muito o Boilerplate. Existe uma maneira mais fácil de compor funções em Java?
Solução
Em Java, isso é muito difícil, pois não há suporte de primeira classe para funções (ao contrário de Clojure ou Scala e provavelmente outras).
No entanto, você pode encapsular a operação em um objeto:
interface Function<R, T> {
R call(T... input);
}
Em seguida, refator Foo
Como:
static <R, T> R runFunction(Function<R, T> function, T ... input){
try{
return function.call(input);
} catch(NullPointerException _null){
m_Logger.error("Null error exception caught in Blah::Foo");
return null;
} catch(Exception ex){
m_Logger.error( ex.getMessage() );
return null;
}
}
caso de teste:
class SumDoubles implements Function<Double, Double> {
@Override
public Double call(Double... input) {
Double sum = 0.0;
for (Double d : input) {
sum += d;
}
return sum;
}
}
@Test
public void sum() {
Double sum = runFunction(new SumDoubles(), 1.0, 2.0, 3.0);
assertThat(sum, is(6.0));
}
Outras dicas
Tentar Lambdaj. Ele permite adicionar um pouco de FP ao Java de uma maneira bastante leve e legível. Em particular neste Página do wiki de fechamento Você pode encontrar um exemplo muito semelhante ao que está tentando alcançar,
Esta é obviamente sua chamada, mas com a maioria das demos de API que eu usei, prefiro o formato mais longo que você tem no topo. Depois de examinar o código, normalmente copio e colo para verificar se a API funciona como eu acho que o modifica a partir daí. Mudar o formato para ocultar algumas das peças repetitivas é definitivamente o que você deseja fazer para o desenvolvimento do OO, mas acho que esse tipo de código de demonstração é algo que os 'Deuses do Código Limpo' entenderiam :-).
Não há como fazer isso em Java, mas tente usar o Groovy se for possível para você. A outra opção que você pode ter embalagem semelhante está usando o aspecto. Vejo aspecto.
Aprendi a maneira como isso é feito em Java é criar uma interface que tenha um método. No seu código, você usa classes implementando essa interface.