Ich habe auf vielen Websites gelesen. Optional sollte nur als Rückgabetyp verwendet und nicht in Methodenargumenten verwendet werden. Ich kämpfe darum, einen logischen Grund dafür zu finden. Zum Beispiel habe ich eine Logik, die 2 optionale Parameter hat. Daher halte ich es für sinnvoll, meine Methodensignatur wie folgt zu schreiben (Lösung 1):
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
Viele Webseiten geben an, dass Optional nicht als Methodenargumente verwendet werden sollte. In diesem Sinne könnte ich die folgende Methodensignatur verwenden und einen eindeutigen Javadoc-Kommentar hinzufügen, um anzugeben, dass die Argumente null sein können, in der Hoffnung, dass zukünftige Betreuer das Javadoc lesen und daher vor der Verwendung der Argumente immer Nullprüfungen durchführen (Lösung 2). ::
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
Alternativ könnte ich meine Methode durch vier öffentliche Methoden ersetzen, um eine schönere Schnittstelle bereitzustellen und klarer zu machen, dass p1 und p2 optional sind (Lösung 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
}
Jetzt versuche ich, den Code der Klasse zu schreiben, die diese Logik für jeden Ansatz aufruft. Optional
Ich rufe zuerst die beiden Eingabeparameter von einem anderen Objekt ab, das s zurückgibt, und rufe dann auf calculateSomething
. Wenn also Lösung 1 verwendet wird, würde der aufrufende Code folgendermaßen aussehen:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);
Wenn Lösung 2 verwendet wird, sieht der aufrufende Code folgendermaßen aus:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));
Wenn Lösung 3 angewendet wird, könnte ich den obigen Code verwenden oder den folgenden (aber es ist deutlich mehr 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();
}
}
Meine Frage lautet also: Warum wird es als schlechte Praxis angesehen, Optional
s als Methodenargumente zu verwenden (siehe Lösung 1)? Es scheint mir die am besten lesbare Lösung zu sein und macht deutlich, dass die Parameter für zukünftige Betreuer leer / null sein können. (Ich bin mir bewusst, dass die Designer Optional
beabsichtigt haben, es nur als Rückgabetyp zu verwenden, aber ich kann keine logischen Gründe finden, es in diesem Szenario nicht zu verwenden.)
null
?