Comment puis-je associer une Chaîne à une fonction en Java?
Actuellement, j'ai un tas de classes Java qui implémentent une Processor
de l'interface, ce qui signifie qu'ils ont tous un processRequest(String key)
méthode. L'idée est que chaque classe a un peu (disons, <10) membre Strings
, et chacune de ces cartes à une méthode de la classe via le processRequest
méthode, comme suit:
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...
}
Vous obtenez l'idée.
Cela fonctionnait très bien pour moi, mais maintenant j'ai besoin de l'exécution, accessible cartographie de la clé de fonction; pas chaque fonction fait retourne une Chaîne de caractères (un peu de retour void) et j'ai besoin d'accéder dynamiquement le type de retour (à l'aide de la réflexion) de chaque fonction dans chaque catégorie, il y a une clé pour. J'ai déjà un gestionnaire qui connaît toutes les clés, mais pas la cartographie de touche de fonction.
Mon premier instinct a été de remplacer cette cartographie à l'aide de if-else
états Map<String, Function>
, comme j'ai pu le faire en Javascript. Mais, Java n'a pas de soutien de première classe de fonctions, donc je suis hors de la chance. Je pourrais sans doute creuser jusqu'à un tiers de bibliothèque qui me permet de travailler avec des fonctions de classe, mais je n'ai pas vu encore, et je doute que j'ai besoin d'une toute nouvelle bibliothèque.
J'ai aussi pensé à mettre ces String
clés dans un tableau et en utilisant la réflexion d'appeler les méthodes par son nom, mais je vois deux inconvénients à cette méthode:
- Mes clés devrait être le même nom que la méthode ou à être nommé dans un particulier, de manière cohérente, de sorte qu'il est facile de les mapper sur le nom de la méthode.
- Cela semble beaucoup plus lent que la
if-else
déclarations que j'ai droit. L'efficacité est quelque chose de préoccupant, parce que ces méthodes ont tendance à être appelé assez souvent, et je veux limiter les frais généraux.
TL; DR: je suis à la recherche d'un endroit propre, à peu de frais généraux pour cartographier un String
à une sorte de Function
objet que je peux appeler et appeler (quelque chose comme) getReturnType()
. Je n'ai pas particulièrement l'esprit à l'aide d'un 3e partie de la bibliothèque si elle vraiment correspond à mes besoins. Je n'ai pas l'esprit à l'aide de la réflexion, je préfère éviter d'utiliser la réflexion à chaque fois que je fais une méthode de recherche - peut-être à l'aide de certains de la mise en cache de la stratégie qui combine les Map
avec la réflexion.
Pensées sur une bonne voie pour obtenir ce que je veux? Cheers!
ouais, c'est typiquement l'endroit où j'étais à la tête à la fin de ma question.
Fait 🙂 🙂 🙂
OriginalL'auteur Matt Ball | 2010-04-30
Vous devez vous connecter pour publier un commentaire.
Ne pouvais pas vous faire
String
àMéthode
? Ensuite, vous pouvez mettre en cache les méthodes que vous devez exécuter.OriginalL'auteur Chris Dennett
Il n'y a pas de première classe autonome des fonctions, mais vous pouvez faire ce que vous voulez avec une interface. Créer une interface qui représente votre fonction. Par exemple, vous pourriez avoir le suivant:
Ensuite, vous pouvez créer un
Map<String,ComputeString>
objet comme vous le souhaitez dans la première place. À l'aide d'une carte sera beaucoup plus rapide que la réflexion et donnera également plus de sécurité du type, donc je vous conseille ci-dessus.C'est totalement maladroit, mais c'est de Java faute de ne pas soutenir directement les fonctions d'ordre supérieur.
oui, c'est maladroit, mais vous pouvez construire des classes anonymes, ce qui devrait le rendre un peu moins maladroit, à l'instar de la carte.mettre(str,nouvelle ComputeString(){public String invoke(){ return "bla"; }});
OriginalL'auteur Michael Aaron Safyan
Alors que vous ne pouvez pas avoir d'abord des fonctions de classe, il y a des classes anonymes qui peut être basé sur une interface:
Ou vous pouvez utiliser Scala 🙂
OriginalL'auteur RoToRa
Ce exemple utilise un
enum
de fonctions nommées et un résuméFunctionAdapter
pour appeler des fonctions avec un nombre variable homogène de paramètres sans réflexion. Lelookup()
fonction utilise simplementEnum.valueOf
, mais unMap
pourrait être utile pour un grand nombre de fonctions.OriginalL'auteur trashgod
Comme vous l'avez remarqué, vous pouvez faire ce que vous voulez à l'aide de la La réflexion de l'API, mais vous perdez certains avantages du compilateur Java, sur les problèmes que vous avez déjà trouvé. Serait habillage de vos Chaînes de caractères dans un objet et à l'aide de la Modèle visiteur résoudre votre problème? Chaque
StringWrapper
n'accepteraient qu'unVisitor
qui a la bonne méthode, ou quelque chose le long de ces lignes.Visitor
fonctionner? Ce serait l'opération?va manger vous - Que je pensais de cette idée, j'ai imaginé le Visiteur visite d'un wrapper pour chaque Chaîne, mais là encore, il semble que vous ne savez pas ce qu'Chaîne s'affiche lorsque. Je suis en train de penser l'Interface idée est beaucoup plus simple.
Visiteur? Utiliser la commande ou de la stratégie de modèle. Les autres réponses montre le modèle de commande. Vous pouvez trouver des exemples concrets de motifs here de sorte que vous pouvez en apprendre un peu plus sur eux.
OriginalL'auteur justkt
L'utilisation d'une Carte où la clé est une chaîne de caractères et la valeur est un objet qui implémente une interface contenant la méthode(). De cette façon, vous pouvez obtenir l'objet contenant la méthode que vous voulez hors de la carte. Puis il suffit d'appeler cette méthode sur l'objet. Par exemple:
OriginalL'auteur mjh2007
Ce sujet Méthode classe à partir de la réflexion de l'API? Vous pouvez trouver des méthodes d'une classe basée sur le nom, les paramètres, ou le type de retour. Ensuite vous suffit d'appeler la Méthode.invoke(ce, paramètres).
C'est à peu près la même chose que la Carte à partir de JavaScript que vous parlez.
OriginalL'auteur Denis Tulskiy