Angekettet invocation in Java 7?
-
06-07-2019 - |
Frage
Ich war gerade das Lesen eine Java 7 Vorschau Präsentation (pdf) und es war eine Folie auf Angekettet Aufruf.Hier ist das Beispiel in der Folie:
// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();
// Construction with chained invocation
Drink margarita = new DrinkBuilder()
.add("tequila")
.add("orange liqueur")
.add("lime juice")
.withRocks()
.withSalt()
.drink();
Und ich habe gemischte Gefühle darüber.Man sollte nicht Kette zu viele Methodenaufrufe in einer Erklärung.Auf der anderen Seite, schreiben margarita.this()
und margarita.that()
nicht allzu bequem, entweder.
Jetzt, ich komme, um von Java aus Delphi-Welt.Und in Delphi gibt es die with
Sprache konstruieren.Dies ist geschätzt von ein paar und verabscheute durch viele (oder ist es Umgekehrt?).Ich finde with
zu werden mehr elegante als die Idee von verketteten Aufruf (die ich glaube, funktioniert auf der basis von void
Methode der Rückkehr Verweis auf Objekt, auf dem es aufgerufen wurde - und dies ist der Teil, den ich nicht mag, als void
sollten zurück nichts).
Ich würde schätzen, die with
Sprache-Funktion angenommen werden, Java, so dass das Beispiel-code geschrieben werden kann, etwa so:
Drink margarita = null;
with (new DrinkBuilder()) {
add("tequila");
add("orange liqueur");
add("lime juice");
withRocks();
withSalt();
margarita = drink();
}
Bin ich der einzige, der lieber diese Lösung zu der verketteten Aufruf?Jemand fühlt, dass with
könnte eine sinnvolle Erweiterung der Sprache Java?(Erinnert mich an jemanden die Frage über die Notwendigkeit von "Java++"...)
Lösung
die mit Anweisung kann übersetzt werden in Java mit anonymen Klassen mit Initialisierer:
Drink margarita = new DrinkBuilder() {{
add(“tequila”);
add(“orange liqueur”);
add(“lime juice”);
withRocks();
withSalt();
}}.drink();
die Nachteile der Verwendung dieser Redewendung sind gut dokumentiert hier.
Angekettet Aufruf ist ein alias für Method Chaining.Bekannte idiom und arbeitet mit jeder Java-version:
class Chained {
public Chained withFoo() {
// ...
return this;
}
public Chained withBar() {
// ...
return this;
}
}
ein Vorschlag für JDK 7 ermöglicht die Verkettung Methode auch für void-return-Typ:
class ChainedJava7 {
public void withFoo() {
// ...
}
public void withBar() {
// ...
}
}
Andere Tipps
Diese Sie interessieren könnte.
Ich mag with
Aussagen dieser Form aber ich ziehe die VB-Version von ihnen:
With testObject
.Height = 100
.Text = "Hello, World"
.ForeColor = System.Drawing.Color.Green
End With
Wie jedes Attribut in der With
Block hat immer noch von einem .
vorausgehen Sie wissen, dass Sie eine Objekteigenschaft sind Referenzierung und nicht, sagen wir, eine lokale Variable, die Verringerung alle Namespace-Kollisionen.
Wenn wir Ihr Beispiel:
with (new DrinkBuilder()) {
add(“tequila”);
add(“orange liqueur”);
add(“lime juice”);
withRocks();
withSalt();
margarita = drink();
}
Es gibt keine einfache Möglichkeit zu sagen, wenn withSalt()
ein Verfahren zur Herstellung DrinkBuilder
oder ein Verfahren in lokaler Klasse. Wenn Sie nur Methoden des with
-ed-Objekt im Block with
erlauben dann denke ich, werden sie sehr viel weniger nützlich.
Ich bin kein Fan von dieser Verwendung von with
; Ich ziehe den Python with
Anweisung . Ich stimme mit Ihnen überein, dass void
void
bedeuten sollte, though. Im Beispiel bieten Sie, wirklich, wenn eine Person an die Kette Methode Anrufungen in der Lage sein möchte, sollte sie nur die Rückgabetypen auf ihre Methoden ändern, so dass sie verkettbar sind.
Vielleicht ist die viele viele Anrufe zu einem Objekt sind das Zeichen, dass einige Code um bewegt werden muss?
Joshua Bloch in Effective Java Item # 2 stark die Verwendung eines empfiehlt Builder, wenn Sie einen Konstruktor mit vielen Argumenten. Ein Grund dafür ist, dass es geschrieben werden kann, um sicherzustellen, dass das integrierte Objekt ist immer in einem konsistenten Zustand. Es vermeidet auch komplexen „Teleskopbauer“ im eingebauten Objektklasse mit. Noch eine andere ist, dass, wenn Sie das integrierte Objekt wollen unveränderlich sein (zB für die Thread-Sicherheit), kann es nicht Setter-Methoden hat.