Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

Dies ist ein von KI übersetzter Beitrag.

제이온

[Effektives Java] Artikel 2. Erwägen Sie einen Builder, wenn der Konstruktor viele Parameter hat

  • Schreibsprache: Koreanisch
  • Referenzland: Alle Länder country-flag

Sprache auswählen

  • Deutsch
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar

Von durumis AI zusammengefasster Text

  • Es werden verschiedene Muster zur effizienten Verwaltung von Konstruktoren mit vielen Parametern vorgestellt, und die Vor- und Nachteile von stufenweisen Konstruktor-Mustern, JavaBeans-Mustern und Builder-Mustern werden verglichen und analysiert.
  • Das Builder-Pattern hat den Vorteil, dass es die Lesbarkeit und Stabilität des Codes verbessert und besonders effektiv ist, wenn es mit hierarchisch gestalteten Klassen verwendet wird.
  • Das Builder-Pattern ermöglicht es, Code übersichtlicher zu gestalten, hat aber den Nachteil, dass ein Builder-Objekt erstellt werden muss und der Code umständlicher sein kann.

Das Stufenmuster des Konstruktors

Sowohl statische Fabriken als auch Konstruktoren haben Schwierigkeiten, mit vielen Parametern umzugehen. Wenn eine Klasse beispielsweise 6 Felder hat und wir Konstruktoren für 2 Parameter, 3 Parameter, ... erstellen möchten, können wir das Stufenmuster des Konstruktors wie folgt verwenden.


public class NutritionFacts {

    private final int servingSize;

    private final int servings;

    private final int calories;

    private final int fat;

    private final int sodium;

    private final int carbohydrate;

    public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {
        this.servingSize = servingSize;
        this.servings = servings;
        this.calories = calories;
        this.fat = fat;
        this.sodium = sodium;
        this.carbohydrate = carbohydrate;
    }

    public NutritionFacts(int servingSize, int servings) {
        this(servingSize, servings, 0, 0, 0, 0);
    }

    public NutritionFacts(int servingSize, int servings, int calories) {
        this(servingSize, servings, calories, 0, 0, 0);
    }

    public NutritionFacts(int servingSize, int servings, int calories, int fat) {
        this(servingSize, servings, calories, fat, 0, 0);
    }

    public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) {
        this(servingSize, servings, calories, fat, sodium, 0);
    }


Aber selbst dann, wenn viele Parameter vorhanden sind, ist es beim Lesen des Codes verwirrend, was die einzelnen Werte bedeuten, und es kann vorkommen, dass Werte mit dem gleichen Typ verwechselt werden.


Java-Beans-Muster

Das Java-Beans-Muster erstellt Objekte mit einem Konstruktor ohne Parameter und ruft dann Setter-Methoden auf, um die gewünschten Parameterwerte zu setzen.


public class NutritionFactsWithJavaBeansPattern {

    private int servingSize = -1; // Erforderlich. Kein Standardwert.

    private int servings = -1; // Erforderlich. Kein Standardwert.

    private int calories;

    private int fat;

    private int sodium;

    private int carbohydrate;

    public void setServingSize(int servingSize) {
        this.servingSize = servingSize;
    }

    public void setServings(int servings) {
        this.servings = servings;
    }

    public void setCalories(int calories) {
        this.calories = calories;
    }

    public void setFat(int fat) {
        this.fat = fat;
    }

    public void setSodium(int sodium) {
        this.sodium = sodium;
    }

    public void setCarbohydrate(int carbohydrate) {
        this.carbohydrate = carbohydrate;
    }


Das Java-Beans-Muster kann Instanzen auch dann erstellen, wenn viele Parameter vorhanden sind, ohne dass die Werte verwechselt werden. Um jedoch ein Objekt zu erstellen, müssen mehrere Setter-Methoden aufgerufen werden, und bevor das Objekt vollständig abgeschlossen ist, wird die Konsistenz beeinträchtigt. Aus diesem Grund kann die Klasse nicht unveränderlich gemacht werden.


Builder-Muster

Das Builder-Muster, das die Stabilität des Stufenmusters des Konstruktors und die Lesbarkeit des Java-Beans-Musters kombiniert, wird häufig verwendet.

Anstelle der direkten Erstellung des gewünschten Objekts ruft der Client einen Konstruktor mit nur den erforderlichen Parametern auf, um ein Builder-Objekt zu erhalten. Anschließend werden die gewünschten optionalen Parameter mithilfe von Setter-Methoden festgelegt, die vom Builder-Objekt bereitgestellt werden. Schließlich wird die build()-Methode ohne Parameter aufgerufen, um das gewünschte Objekt zu erhalten.


public class NutritionFactsWithBuilderPattern {

    private final int servingSize;

    private final int servings;

    private final int calories;

    private final int fat;

    private final int sodium;

    private final int carbohydrate;

    private NutritionFactsWithBuilderPattern(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }

    public static class Builder {

        private final int servingSize;

        private final int servings;

        private int calories;

        private int fat;

        private int sodium;

        private int carbohydrate;

        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val) {
            calories = val;
            return this;
        }

        public Builder fat(int val) {
            fat = val;
            return this;
        }

        public Builder sodium(int val) {
            sodium = val;
            return this;
        }

        public Builder carbohydrate(int val) {
            calories = val;
            return this;
        }

        public NutritionFactsWithBuilderPattern build() {
            return new NutritionFactsWithBuilderPattern(this);
        }
    }


Der Konstruktor in der Builder-Klasse nimmt nur die erforderlichen Parameter entgegen, während die restlichen optionalen Parameter mithilfe von Setter-Methoden gefüllt werden. Schließlich wird die build()-Methode verwendet, um das vollständige NutritionFactsWithBuilderPattern-Objekt zu erstellen. NutritionFactsWithBuilderPattern ist unveränderlich, und da die Setter-Methoden des Builders den Builder selbst zurückgeben, können sie verkettet aufgerufen werden. Diese Methode wird als Fluent API oder Method Chaining bezeichnet.


NutritionFactsWithBuilderPattern nutritionFacts =
    new NutritionFactsWithBuilderPattern.Builder(240, 8)
        .calories(100)
        .sodium(35)


Aus der Sicht des Clients kann der Code mit dem Builder-Muster einfach geschrieben und gelesen werden.


Das Builder-Muster, das gut zu hierarchisch gestalteten Klassen passt

public abstract class Pizza {

    public enum Topping {
        HAM, MUSHROOM, ONION, PEPPER, SAUSAGE
    }

    final Set toppings;

    Pizza(Builder builder) {
        toppings = builder.toppings.clone();
    }

    abstract static class Builder> {

        private EnumSet toppings = EnumSet.noneOf(Topping.class);

        public T addTopping(Topping topping) {
            toppings.add(topping);
            return self();
        }

        abstract Pizza build();

        protected abstract T self();
    }


Die Pizza.Builder-Klasse ist ein generischer Typ, der rekursive Typspezifikationen verwendet, und die abstrakte Methode self() wurde hinzugefügt, um eine Methodenverkettung zu ermöglichen, ohne dass Unterklassen Typumwandlungen durchführen müssen. Unterklassen können den Rückgabewert dieser abstrakten Methode einfach auf sich selbst setzen.

Betrachten wir nun die Unterklassen New Yorker Pizza und Calzone-Pizza von Pizza und erleben die Flexibilität des Builder-Musters.


public class NyPizza extends Pizza {

    public enum Size {
        SMALL, MEDIUM, LARGE
    }

    private final Size size; // Erforderlicher Parameter

    private NyPizza(Builder builder) {
        super(builder);
        size = builder.size;
    }

    public static class Builder extends Pizza.Builder {

        private final Size size;

        public Builder(Size size) {
            this.size = size;
        }

        @Override
        NyPizza build() {
            return new NyPizza(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }

}

public class CalzonePizza extends Pizza {

    private final boolean sauceInside; // Optionaler Parameter

    private CalzonePizza(Builder builder) {
        super(builder);
        sauceInside = builder.sauceInside;
    }

    public static class Builder extends Pizza.Builder {

        private boolean sauceInside = false;

        public Builder sauceInside() {
            sauceInside = true;
            return this;
        }

        @Override
        CalzonePizza build() {
            return new CalzonePizza(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }


Die build()-Klasse, die in der Builder jeder Unterklasse definiert ist, gibt die konkrete Unterklasse zurück. Die Fähigkeit einer Unterklassenmethode, einen Typ zurückzugeben, der nicht der von der Oberklassenmethode zurückgegebene Typ ist, sondern ein Untertyp davon, wird als kovariantes Rückgabetypisieren bezeichnet. Mit dieser Funktion muss der Client keine Typumwandlung durchführen.


NyPizza nyPizza = new NyPizza.Builder(Size.SMALL)
    .addTopping(Topping.SAUSAGE)
    .addTopping(Topping.ONION)
    .build();

CalzonePizza calzonePizza = new CalzonePizza.Builder()
    .addTopping(Topping.HAM)
    .sauceInside()


Der Client kann das enum von Pizza und das enum jeder Unterklasse mischen und das Objekt mit den entsprechenden Methoden vervollständigen.


Nachteile des Builder-Musters

  • Es muss ein Builder-Objekt erstellt werden.
  • Der Code ist umfangreich.


Zusammenfassung

Wenn ein Konstruktor oder eine statische Fabrikmethode viele Parameter verarbeiten muss, sollte das Builder-Muster in Betracht gezogen werden.


Quelle

  • Effektives Java
제이온
제이온
제이온
제이온
[Effektives Java] Item 1. Statische Fabrikmethoden in Betracht ziehen Statische Fabrikmethoden sind eine flexible und effiziente Möglichkeit, Instanzen zu erstellen, anstatt Konstruktoren zu verwenden. Sie können benannt werden, Instanzen zurückgeben, die bestimmten Bedingungen entsprechen, und die Leistung durch Caching ve

27. April 2024

[Effektives Java] Artikel 4. Verwenden Sie einen privaten Konstruktor, um die Instanziierung zu verhindern Bei Utility-Klassen, die nur statische Methoden und Felder enthalten, sollten Sie den Zugriffsschutzmodifizierer des Konstruktors auf private setzen, um die Instanziierung zu verhindern. Dadurch wird verhindert, dass Benutzer den Konstruktor für automatis

28. April 2024

[Effektives Java] Punkt 5: Verwenden Sie Dependency Injection anstelle von expliziten Ressourcen Wenn eine Klasse von externen Ressourcen abhängt, sollten Singleton- und statische Utility-Klassen vermieden werden. Durch Dependency Injection können Sie die Flexibilität, Wiederverwendbarkeit und Testbarkeit der Klasse verbessern. Die Verwendung des Fac

28. April 2024

[Nicht-Hauptfach, Überleben als Entwickler] 14. Zusammenfassung der häufigen technischen Vorstellungsgesprächsinhalte für Einsteiger Dieser Leitfaden ist für die Vorbereitung auf technische Vorstellungsgespräche für Einsteiger. Hauptspeicherbereich, Datenstrukturen, RDBMS und NoSQL, prozedurale und objektorientierte Programmierung, Überladen und Überschreiben, Seitenersatzzustände, Pro
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3. April 2024

[Nicht-Major, Entwickler überleben] 13. Technisches Vorstellungsgespräch für Einsteiger Dieser Artikel stellt 7 häufig gestellte Fragen in technischen Vorstellungsgesprächen für Einsteiger vor und bietet Tipps zur Vorbereitung auf das Vorstellungsgespräch. Erfahren Sie mehr über Fragen und Antwortstrategien in verschiedenen Bereichen wie OOP
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

1. April 2024

Wie Rust Konsistenzfehler verhindert Rust ist eine leistungsstarke Sprache, die die Herausforderungen der konkurrenten Programmierung bewältigt. Dank des Typsystems und des Besitzmodells ist der Datenaustausch und die gemeinsame Nutzung zwischen Threads sicher. Durch Muster der internen Vari
곽경직
곽경직
곽경직
곽경직
곽경직

28. März 2024

[Javascript] Objektstruktur (V8) Das JavaScript-Objekt wird in der V8-Engine je nach Zustand als strukturierte, optimierte Fast-Mode oder als Hashmap-basierter Dictionary-Mode dargestellt. Der Fast-Mode ist schnell, wenn Schlüssel und Werte fast fixiert sind, aber bei der Hinzufügung neu
곽경직
곽경직
곽경직
곽경직
곽경직

18. März 2024

[Nicht-Fachmann, Überleben als Entwickler] 16. Tipps für die Erstellung eines Portfolios für Einsteiger Ein Einsteigerentwickler (insbesondere Nicht-Fachmann) muss bei der Erstellung eines Portfolios nicht nur die Technologie, sondern auch die entwickelten Dienste oder Funktionen klar erläutern. Zum Beispiel, wenn es sich um ein "Jobsuchenden-Community"-Pro
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3. April 2024

[Metallwerkstoff-Meisterprüfung Praxis] 33. Ausgabe gelöst Metallische Werkstoffe, Kristallstruktur, Perlit-Nukleationsvorgang, Ferrit-Kristallkorngrößenmessmethode, die fünf Hauptbestandteile von Stahl und der Einfluss von Mangan, Maßnahmen zur Vermeidung von Anlassversagen, Eigenschaften des Abschreckens, Berec
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi

23. April 2024