Ihr Hauptfehler ist, dass Sie immer noch prozeduraler denken. Dies ist nicht als Kritik an Ihnen als Person gedacht, sondern lediglich eine Beobachtung. Funktionaleres Denken ist mit Zeit und Übung verbunden, und daher sind die Methoden „Präsentieren“ und „Schauen“, wie die offensichtlichsten richtigen Dinge aussehen, die für Sie in Frage kommen. Ihr zweiter kleiner Fehler ist das Erstellen Ihrer Option in Ihrer Methode. Die Option soll dokumentieren, dass etwas einen Wert zurückgeben kann oder nicht. Sie könnten nichts bekommen.
Dies hat dazu geführt, dass Sie perfekt lesbaren Code geschrieben haben, der absolut vernünftig erscheint, aber Sie wurden von den abscheulichen Zwillingsversuchern verführt, die get und isPresent sind.
Natürlich wird die Frage schnell: "Warum sind wir präsent und kommen auch dort an?"
Eine Sache, die viele Leute hier vermissen, ist, dass isPresent () ist, dass es nicht für neuen Code gemacht ist, der von Leuten geschrieben wurde, die voll an Bord sind und wissen, wie verdammt nützliche Lambdas sind und wer die funktionale Sache mag.
Es gibt uns jedoch ein paar (zwei) gute, großartige, glamouröse (?) Vorteile:
- Es vereinfacht den Übergang von altem Code, um die neuen Funktionen zu nutzen.
- Es erleichtert die Lernkurven von Optional.
Der erste ist ziemlich einfach.
Stellen Sie sich vor, Sie haben eine API, die so aussieht:
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();
}
Und Sie hatten eine Legacy-Klasse, die dies als solches verwendete (füllen Sie die Lücken aus):
Snickers lastSnickers = snickersCounter.lastConsumedSnickers();
if(null == lastSnickers) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers);
}
Ein erfundenes Beispiel, um sicher zu sein. Aber ertrage es hier mit mir.
Java 8 wurde nun gestartet und wir bemühen uns, an Bord zu kommen. Eines der Dinge, die wir tun, ist, dass wir unsere alte Schnittstelle durch etwas ersetzen möchten, das Optional zurückgibt. Warum? Denn wie jemand anderes schon gnädig gesagt hat:
Dies nimmt die Vermutung auf sich, ob etwas null sein kann oder nicht.
Dies wurde bereits von anderen hervorgehoben. Aber jetzt haben wir ein Problem. Stellen Sie sich vor, wir haben (entschuldigen Sie, während ich bei einer unschuldigen Methode Alt + F7 drücke) 46 Stellen, an denen diese Methode in gut getestetem Legacy-Code aufgerufen wird, der ansonsten hervorragende Arbeit leistet. Jetzt müssen Sie alle aktualisieren.
Hier erstrahlt isPresent.
Denn jetzt: Snickers lastSnickers = snickersCounter.lastConsumedSnickers (); if (null == lastSnickers) {wirf eine neue NoSuchSnickersException (); } else {consumer.giveDiabetes (lastSnickers); }
wird:
Optional<Snickers> lastSnickers = snickersCounter.lastConsumedSnickers();
if(!lastSnickers.isPresent()) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers.get());
}
Und dies ist eine einfache Änderung, die Sie dem neuen Junior geben können: Er kann etwas Nützliches tun und gleichzeitig die Codebasis erkunden. Win-Win. Immerhin ist so etwas ziemlich verbreitet. Und jetzt müssen Sie den Code nicht mehr umschreiben, um Lambdas oder ähnliches zu verwenden. (In diesem speziellen Fall wäre es trivial, aber ich überlasse es dem Leser, sich Beispiele auszudenken, bei denen es als Übung schwierig wäre.)
Beachten Sie, dass dies bedeutet, dass die Art und Weise, wie Sie dies getan haben, im Wesentlichen ein Weg ist, mit Legacy-Code umzugehen, ohne kostspielige Umschreibungen vorzunehmen. Was ist mit neuem Code?
Nun, in Ihrem Fall, in dem Sie nur etwas ausdrucken möchten, tun Sie einfach Folgendes:
snickersCounter.lastConsumedSnickers (). ifPresent (System.out :: println);
Das ist ziemlich einfach und vollkommen klar. Der Punkt, der dann langsam an die Oberfläche sprudelt, ist, dass es Use Cases für get () und isPresent () gibt. Mit ihnen können Sie vorhandenen Code mechanisch ändern, um die neueren Typen zu verwenden, ohne zu viel darüber nachzudenken. Was Sie tun, ist daher auf folgende Weise falsch:
- Sie rufen eine Methode auf, die möglicherweise null zurückgibt. Die richtige Idee wäre, dass die Methode null zurückgibt.
- Sie verwenden die herkömmlichen Bandaid-Methoden, um dieses optionale Problem zu lösen, anstatt die leckeren neuen Methoden zu verwenden, die Lambda-Phantasie enthalten.
Wenn Sie Optional als einfache Null-Sicherheitsüberprüfung verwenden möchten, sollten Sie Folgendes tun:
new Optional.ofNullable(employeeServive.getEmployee())
.map(Employee::getId)
.ifPresent(System.out::println);
Natürlich sieht die gut aussehende Version so aus:
employeeService.getEmployee()
.map(Employee::getId)
.ifPresent(System.out::println);
Übrigens, obwohl es keinesfalls erforderlich ist, empfehle ich, pro Operation eine neue Zeile zu verwenden, damit es einfacher zu lesen ist. Leicht zu lesende und verständliche Beats prägnant an jedem Wochentag.
Dies ist natürlich ein sehr einfaches Beispiel, in dem es einfach ist, alles zu verstehen, was wir versuchen zu tun. Im wirklichen Leben ist es nicht immer so einfach. Beachten Sie jedoch, dass wir in diesem Beispiel unsere Absichten zum Ausdruck bringen. Wir möchten den Mitarbeiter abrufen, seinen Ausweis abrufen und ihn, falls möglich, ausdrucken. Dies ist der zweite große Gewinn mit Optional. Dadurch können wir klareren Code erstellen. Ich denke auch, dass es im Allgemeinen eine gute Idee ist, Dinge wie die Erstellung einer Methode zu tun, die eine Reihe von Dingen ausführt, damit Sie sie einer Karte hinzufügen können.