Posso darti una risposta piuttosto generica che ritengo sia adatta solo a casi d'uso più complessi a causa dell'eccessiva richiesta di piastra di riscaldamento. È possibile simulare perfettamente un paradigma funzionale in Java (lo hanno fatto in Scala) e utilizzare, ad esempio, lo schema di decorazione per risolvere il problema. L'approccio generale consiste nel definire una classe astratta o un'interfaccia con un singolo metodo che possa quindi essere sovrascritta da una classe interna anonima.
Semplice esempio per il tuo caso d'uso:
public class SimpleDecorator {
public static void main(String[] args) {
new PrintingDecorator() {
protected void execute() {
System.out.println("Calling my first function");
}
}.apply();
new PrintingDecorator() {
protected void execute() {
System.out.println("Calling my second function");
}
}.apply();
}
}
abstract class PrintingDecorator {
public void apply(){
System.out.println("Doing this action before");
execute();
System.out.println("Doing this action after");
}
protected abstract void execute();
}
Esecuzione di queste stampe:
Doing this action before
Calling my first function
Doing this action after
Doing this action before
Calling my second function
Doing this action after
Ora potresti andare molto più lontano e in effetti solo definire le funzioni e così basare il tuo decoratore su questo. Quindi per l'esempio inutilmente complesso:
public class FunctionalDecorator {
public static void main(String[] args) {
Function1<Function0<Void>, Function0<Void>> printDecorator = new Function1<Function0<Void>, Function0<Void>>() {
public Function0<Void> apply(final Function0<Void> arg1) {
Function0<Void> resultFunc = new Function0<Void>() {
public Void apply() {
System.out.println("Doing this action before");
arg1.apply();
System.out.println("Doing this action after");
return null;
}
};
return resultFunc;
}
};
printDecorator.apply(
new Function0<Void>() {
public Void apply() {
System.out.println("Calling my first function");
return null;
}
}
).apply();
//Slightly more complex example (with taking arguments and returning values)
Function1<Function1<String, String>, Function1<String, String>> addTextDecorator = new Function1<Function1<String,String>, Function1<String,String>>() {
public Function1<String, String> apply(final Function1<String, String> funcArg) {
Function1<String, String> resultFunc = new Function1<String, String>() {
public String apply(String arg1) {
return "Before string\t" + funcArg.apply(arg1) + "\tAfter string";
}
};
return resultFunc;
}
};
Function1<String, String> echo = new Function1<String, String>() {
public String apply(String arg1) {
return arg1;
}
};
Function1<String, String> decoratedEcho = addTextDecorator.apply(echo);
System.out.println(decoratedEcho.apply("Echo!"));
}
}
interface Function0<ReturnType> {
public ReturnType apply();
}
interface Function1<ArgType1, ReturnType>{
public ReturnType apply(ArgType1 arg1);
}
abstract class Decorator implements Function0<Void>{
private Function0<Void> func;
public Decorator(Function0<Void> func){
this.func = func;
}
public Void apply() {
beforeAction();
Void result = func.apply();
afterAction();
return result;
}
protected abstract void beforeAction();
protected abstract void afterAction();
}
class PrintDecorator extends Decorator {
public PrintDecorator(Function0<Void> func) {
super(func);
}
protected void beforeAction() {
System.out.println("Doing this action before");
}
protected void afterAction() {
System.out.println("Doing this action after");
}
}
Esecuzione di queste stampe:
Doing this action before
Calling my first function
Doing this action after
Before string Echo! After string