Bloc try-catch Fluent [fermé]
J'ai beaucoup de code de ce type dans mon application:
String authUserId = null;
try {
authUserId = webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
} catch (Exception e) {
// do nothing
}
Avec chaque fragment, l'objectif est d'attribuer une valeur si la méthode n'a pas lancé, null sinon. Et bien que le code ci-dessus fonctionne, il semble certainement redondant et non simplifié.
Quelle bibliothèque Java peut rendre ce code plus fluide? Comme:
String authUserId = Try<String>.of(try -> {
return webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
});
ou quelque chose de plus simple.
METTRE À JOUR:
Utilisation de la bibliothèque Vavr
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.3</version>
</dependency>
Résolu ceci avec:
String authUserId = Try.of(() -> webTokenService.readUserIdFromToken(app.getMasterKey(), authToken)).get();
Réponses
Si vous avalez complètement l'exception, ce n'est pas vraiment la meilleure pratique . Il y a un bel article sur l'exception de Baeldung:
Ce qui précède est appelé avaler une exception. La plupart du temps, ce serait un peu méchant pour nous de le faire, car cela ne résout pas le problème et cela empêche également d'autres codes de résoudre le problème.
J'ai trouvé une bibliothèque qui implémente ce comportement. Cependant, il n'a pas été maintenu depuis un certain temps. Pour cette raison, je recommanderais plutôt Vavr . Il est toujours nécessaire de gérer l'exception. Un autre tutoriel est également disponible auprès de Baeldung . Dans la documentation, il y a un petit exemple de division de deux nombres:
int divide(int dividend, int divisor) {
return dividend / divisor;
}
Try<Integer> divide(Integer dividend, Integer divisor) {
return Try.of(() -> dividend / divisor);
}
Étant donné qu'il est stupide d'avaler des exceptions en silence, aucune.
C'est tout à fait trivial d'écrire une telle chose vous-même:
class ShootMyselfInLegToolkit {
@FunctionalInterface
public interface PermissiveSupplier<T> {
T supply() throws Exception;
}
public <T> T ohMyLegs(PermissiveSupplier<T> supplier) {
try {
return supplier.supply();
} catch (Exception itHurts) {
return null; // dear lord.
}
}
}
Si vous voulez vraiment pousser ça dans une bibliothèque, par tous les moyens.
Les bibliothèques fonctionnelles un peu moins idiotes fonctionnent comme ceci: Vous fournissez à la fois un fournisseur (permissif - le jufSupplier de java ne peut pas le faire) et un gestionnaire d'exceptions, donc cela ressemble à:
Tool.tryGet(() -> Files.readAllLines(Paths.get("foo.txt")), ioex -> { code to handle the exception });
Vous ne pouvez pas simplement y aller: Hé, pas de crochets, donc je n'appuie jamais sur Entrée, et donc c'est `` moins de lignes de code '' et donc, `` plus simple '', c'est ... eh bien, un mode de pensée très étrange que vous avez là.
Que signifie, selon vos propres termes, «fluent»? Je reconnais le terme appliqué aux méthodes setters, getters et builder, et cela signifie: "Pas de préfixe get / set". Cela ne s'applique évidemment pas ici, alors vous pensez clairement que cela signifie autre chose. Ce n'est pas dans la spécification java lang, donc peut-être élaboré.
Je ne vois pas comment tout cela est plus simple à comprendre ou plus facile à programmer, mis à part les combats de style idiots. Je pense que la plupart seraient d'accord pour dire que l'introduction de tout un tas de bibliothèques folles JUSTE parce que vous trouvez le style couramment utilisé dans la communauté Java odieux - c'est une mauvaise solution. Écrire du code de manière non idiomatique est une mauvaise idée, quelle que soit la langue et peu importe à quel point vous détestez le style commun. Utilisez simplement une autre langue ou ajustez vos goûts de style. Plus facile à dire qu'à faire, peut-être, mais néanmoins - la meilleure idée, de loin.