J'ai lu sur de nombreux sites Web. Facultatif doit être utilisé uniquement comme type de retour et non utilisé dans les arguments de méthode. J'ai du mal à trouver une raison logique pour laquelle. Par exemple, j'ai un morceau de logique qui a 2 paramètres facultatifs. Par conséquent, je pense qu'il serait logique d'écrire ma signature de méthode comme ceci (solution 1):
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
De nombreuses pages Web spécifient que Facultatif ne doit pas être utilisé comme arguments de méthode. Dans cet esprit, je pourrais utiliser la signature de méthode suivante et ajouter un commentaire Javadoc clair pour spécifier que les arguments peuvent être nuls, en espérant que les futurs responsables liront le Javadoc et effectueront donc toujours des vérifications nulles avant d'utiliser les arguments (solution 2) :
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
Alternativement, je pourrais remplacer ma méthode par quatre méthodes publiques pour fournir une interface plus agréable et la rendre plus évidente p1 et p2 sont facultatifs (solution 3):
public int calculateSomething() {
calculateSomething(null, null);
}
public int calculateSomething(String p1) {
calculateSomething(p1, null);
}
public int calculateSomething(BigDecimal p2) {
calculateSomething(null, p2);
}
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
J'essaie maintenant d'écrire le code de la classe qui invoque ce morceau de logique pour chaque approche. Je récupère d'abord les deux paramètres d'entrée d'un autre objet qui retourne Optional
s puis, j'invoque calculateSomething
. Par conséquent, si la solution 1 est utilisée, le code appelant ressemblerait à ceci:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);
si la solution 2 est utilisée, le code appelant ressemblerait à ceci:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));
si la solution 3 est appliquée, je pourrais utiliser le code ci-dessus ou je pourrais utiliser ce qui suit (mais c'est beaucoup plus de code):
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result;
if (p1.isPresent()) {
if (p2.isPresent()) {
result = myObject.calculateSomething(p1, p2);
} else {
result = myObject.calculateSomething(p1);
}
} else {
if (p2.isPresent()) {
result = myObject.calculateSomething(p2);
} else {
result = myObject.calculateSomething();
}
}
Ma question est donc la suivante: pourquoi est-il considéré comme une mauvaise pratique d'utiliser Optional
s comme arguments de méthode (voir la solution 1)? Cela ressemble à la solution la plus lisible pour moi et rend plus évident que les paramètres pourraient être vides / nuls pour les futurs responsables. (Je sais que les concepteurs l'ont Optional
prévu pour être utilisé uniquement comme type de retour, mais je ne trouve aucune raison logique de ne pas l'utiliser dans ce scénario).
null
?