Attualmente, ho un sacco di classi Java che implementano un'interfaccia Processor
, il che significa che hanno tutti un metodo processRequest(String key)
. L'idea è che ogni classe ha un membro di alcuni (per esempio, < 10) Strings
, e ciascuna di queste mappe ad un metodo di quella classe attraverso il metodo processRequest
, in questo modo:Come posso mappare una stringa a una funzione in Java?
class FooProcessor implements Processor
{
String key1 = "abc";
String key2 = "def";
String key3 = "ghi";
// and so on...
String processRequest(String key)
{
String toReturn = null;
if (key1.equals(key)) toReturn = method1();
else if (key2.equals(key)) toReturn = method2();
else if (key3.equals(key)) toReturn = method3();
// and so on...
return toReturn;
}
String method1() { // do stuff }
String method2() { // do other stuff }
String method3() { // do other other stuff }
// and so on...
}
Si ottiene l'idea.
Questo funzionava bene per me, ma ora ho bisogno di un mapping accessibile in runtime da chiave a funzione; non tutte le funzioni in realtà restituiscono una stringa (alcuni return void) e ho bisogno di accedere dinamicamente al tipo restituito (usando reflection) di ogni funzione in ogni classe per cui esiste una chiave. Ho già un manager che conosce tutte le chiavi, ma non la mappatura da chiave a funzione.
Il mio primo istinto è stato quello di sostituire questa mappatura utilizzando le dichiarazioni if-else
con un Map<String, Function>
, come avrei potuto fare in Javascript. Ma Java non supporta le funzioni di prima classe, quindi sono sfortunato. Probabilmente potrei trovare una libreria di terze parti che mi permetta di lavorare con funzioni di prima classe, ma non ne ho ancora viste, e dubito che abbia bisogno di un'intera nuova libreria.
Ho anche pensato di mettere questi String
chiavi in un array e l'utilizzo di riflessione per richiamare i metodi per nome, ma vedo due aspetti negativi a questo metodo:
- mie chiavi dovrebbero essere chiamato lo stesso il metodo - o essere nominato in un modo particolare, coerente in modo che sia facile mapparli al nome del metodo.
- Questo sembra più lento delle dichiarazioni
if-else
che ho adesso. L'efficienza è una preoccupazione, perché questi metodi tendono a essere chiamati abbastanza frequentemente, e voglio ridurre al minimo i costi non necessari.
TL; DR: Sto cercando un modo pulito, minimale per mappare uno String
in una sorta di oggetto Function
che posso richiamare e chiamare (qualcosa di simile) getReturnType()
su. Non mi interessa in particolare l'utilizzo di una libreria di terze parti se è in realtà adatta alle mie esigenze. Inoltre, non mi dispiace usare il reflection, anche se preferirei fortemente evitare di usare reflection ogni volta che eseguo una ricerca di metodo - magari usando una strategia di caching che combini lo Map
con la riflessione.
Pensieri su un buon modo per ottenere quello che voglio? Saluti!
Non si può eseguire il comando String to Method (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Method.html)? Quindi puoi memorizzare nella cache i metodi che devi eseguire. –
@Chris - sì, questo è praticamente il punto in cui stavo andando alla fine della mia domanda. –
Fatto :) :) :) –