Votre erreur principale est que vous envisagez toujours de manière plus procédurale. Ceci n'est pas conçu comme une critique de vous en tant que personne, c'est simplement une observation. Penser en termes plus fonctionnels va de pair avec le temps et la pratique. Par conséquent, les méthodes sont actuelles et donnent l’impression que les choses correctes les plus évidentes s’appellent à vous. Votre erreur mineure secondaire est la création de votre option dans votre méthode. Facultatif est conçu pour aider à documenter le fait que quelque chose peut ou non renvoyer une valeur. Vous pourriez ne rien obtenir.
Cela vous a conduit à écrire un code parfaitement lisible qui semble parfaitement raisonnable, mais vous avez été séduit par les viles tentacules jumelles qui se font et sont présentes.
Bien sûr, la question devient rapidement "pourquoi sont-ils présents et même y arriver?"
Une chose qui manque à beaucoup de gens ici, c'est que isPresent () est que ce n'est pas quelque chose qui est fait pour le nouveau code écrit par des gens pleinement conscients de l'utile dieu que sont les lambda, et qui aime le fonctionnel.
Cependant, il nous donne quelques (deux) bons, grands avantages glamour (?):
- Il facilite la transition du code hérité pour utiliser les nouvelles fonctionnalités.
- Il facilite les courbes d'apprentissage de facultatif.
Le premier est plutôt simple.
Imaginez que vous ayez une API qui ressemble à ceci:
public interface SnickersCounter {
/**
* Provides a proper count of how many snickers have been consumed in total.
*/
public SnickersCount howManySnickersHaveBeenEaten();
/**
* returns the last snickers eaten.<br>
* If no snickers have been eaten null is returned for contrived reasons.
*/
public Snickers lastConsumedSnickers();
}
Et vous aviez une classe héritée utilisant ceci en tant que tel (complétez les blancs):
Snickers lastSnickers = snickersCounter.lastConsumedSnickers();
if(null == lastSnickers) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers);
}
Un exemple artificiel pour être sûr. Mais supporte avec moi ici.
Java 8 est maintenant lancé et nous nous efforçons de monter à bord. L’une des choses que nous faisons est donc de remplacer notre ancienne interface par quelque chose qui retourne facultatif. Pourquoi? Parce que, comme quelqu'un d'autre l'a déjà gracieusement mentionné:
Cela élimine la question de savoir si quelque chose peut être nul ou non.
Cela a déjà été souligné par d'autres. Mais maintenant nous avons un problème. Imaginez que nous ayons (excusez-moi pendant que je frappe alt + F7 une méthode innocente), 46 endroits où cette méthode est appelée dans un code hérité bien testé qui fait un excellent travail sinon. Maintenant, vous devez mettre à jour tous ces éléments.
C’est là que brille isPresent.
Parce que maintenant: Snickers lastSnickers = snickersCounter.lastConsumedSnickers (); if (null == lastSnickers) {lance la nouvelle NoSuchSnickersException (); } else {consumer.giveDiabetes (lastSnickers); }
devient:
Optional<Snickers> lastSnickers = snickersCounter.lastConsumedSnickers();
if(!lastSnickers.isPresent()) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers.get());
}
Et ceci est un changement simple que vous pouvez donner au nouveau junior: il peut faire quelque chose d’utile, et il va pouvoir explorer le code en même temps. gagnant-gagnant. Après tout, quelque chose qui ressemble à ce modèle est assez répandu. Et maintenant, vous n'avez pas à réécrire le code pour utiliser des lambdas ou quoi que ce soit. (Dans ce cas particulier, ce serait trivial, mais je laisse penser au lecteur des exemples où ce serait difficile comme exercice.)
Notez que cela signifie que votre façon de faire est essentiellement une façon de traiter le code hérité sans faire de réécriture coûteuse. Alors, qu'en est-il du nouveau code?
Eh bien, dans votre cas, où vous voulez simplement imprimer quelque chose, vous feriez simplement:
snickersCounter.lastConsumedSnickers (). ifPresent (System.out :: println);
Ce qui est assez simple et parfaitement clair. Le point qui remonte lentement à la surface est qu’il existe des cas d’utilisation pour get () et isPresent (). Ils sont là pour vous permettre de modifier mécaniquement le code existant pour utiliser les nouveaux types sans trop y penser. Ce que vous faites est donc malavisé des manières suivantes:
- Vous appelez une méthode qui peut renvoyer null. L'idée correcte serait que la méthode retourne null.
- Vous utilisez les méthodes héritées du pansement pour traiter cette option, au lieu d'utiliser les nouvelles méthodes savoureuses qui contiennent la fantaisie lambda.
Si vous souhaitez utiliser facultatif comme simple contrôle de sécurité null, vous devez simplement procéder comme suit:
new Optional.ofNullable(employeeServive.getEmployee())
.map(Employee::getId)
.ifPresent(System.out::println);
Bien sûr, la belle version de ceci ressemble à ceci:
employeeService.getEmployee()
.map(Employee::getId)
.ifPresent(System.out::println);
En passant, bien que cela ne soit absolument pas nécessaire, je recommande d’utiliser une nouvelle ligne par opération, afin de faciliter la lecture. Facile à lire et à comprendre bat la concision tous les jours de la semaine.
Ceci est bien sûr un exemple très simple où il est facile de comprendre tout ce que nous essayons de faire. Ce n'est pas toujours aussi simple dans la vie réelle. Mais remarquez comment dans cet exemple, ce que nous exprimons sont nos intentions. Nous voulons OBTENIR l'employé, OBTENIR son identifiant et, si possible, l'imprimer. C'est la deuxième grande victoire avec Optional. Cela nous permet de créer un code plus clair. Je pense aussi que faire des choses comme créer une méthode qui fait beaucoup de choses pour pouvoir l’alimenter sur une carte est en général une bonne idée.