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++"...)

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top