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

Questo è un post tradotto da IA.

제이온

[Effective Java] Item 2. Se hai molti parametri nel costruttore, considera di usare un builder

Seleziona la lingua

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

Testo riassunto dall'intelligenza artificiale durumis

  • Vengono presentati diversi pattern per gestire in modo efficiente i costruttori con molti parametri, analizzando i pro e i contro del pattern del costruttore graduale, del pattern JavaBeans e del pattern builder.
  • Il pattern builder offre i vantaggi di migliorare la leggibilità e la stabilità del codice, ed è particolarmente efficace quando si lavora con classi progettate in modo gerarchico.
  • Il pattern builder consente di scrivere codice più chiaro, ma presenta lo svantaggio di richiedere la creazione di un oggetto builder e di rendere il codice più verboso.

Modello di costruttore graduale

Sia le factory statiche che i costruttori hanno difficoltà a gestire in modo appropriato i parametri multipli. Ad esempio, se una classe ha 6 campi e si desidera creare un costruttore per 2 parametri, per 3 parametri, ... ecc., è possibile utilizzare il modello di costruttore graduale, come mostrato di seguito.



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);
    }


Tuttavia, anche in questo caso, se il numero di parametri è elevato, il codice potrebbe diventare difficile da leggere e potrebbe essere difficile capire il significato di ciascun valore, potendo inoltre confondere i parametri dello stesso tipo durante l'inserimento dei valori.


Modello di Bean Java

Il modello di Bean Java crea un oggetto utilizzando un costruttore senza parametri e quindi chiama i metodi setter per impostare i valori desiderati dei parametri.


public class NutritionFactsWithJavaBeansPattern {

    private int servingSize = -1; // Obbligatorio. Nessun valore predefinito.

    private int servings = -1; // Obbligatorio. Nessun valore predefinito.

    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;
    }


Il modello di Bean Java consente di creare istanze senza confondere i valori, anche se il numero di parametri è elevato. Tuttavia, per creare un oggetto è necessario chiamare più metodi setter e la coerenza potrebbe essere compromessa finché l'oggetto non è completamente completato. Per questo motivo, la classe non può essere resa immutabile.


Modello Builder

Il modello Builder, che combina la sicurezza del modello di costruttore graduale con la leggibilità del modello di Bean Java, è il più utilizzato.

Il client, invece di creare l'oggetto direttamente, chiama il costruttore con solo i parametri obbligatori per ottenere un oggetto Builder. Successivamente, l'oggetto Builder fornisce una sorta di metodi setter per impostare i parametri facoltativi desiderati. Infine, chiama il metodo build() senza parametri per ottenere l'oggetto desiderato.


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);
        }
    }


Il costruttore all'interno della classe Builder accetta solo i parametri obbligatori, mentre gli altri parametri facoltativi vengono riempiti utilizzando una sorta di metodi setter. Infine, il metodo build() crea l'oggetto NutritionFactsWithBuilderPattern completo. La classe NutritionFactsWithBuilderPattern è immutabile e i metodi setter del builder restituiscono il builder stesso, consentendo chiamate a catena. Questo approccio è chiamato API fluente o concatenazione di metodi.


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


Dal punto di vista del client, il modello Builder semplifica la scrittura e la lettura del codice.


Modello Builder adatto a classi progettate gerarchicamente

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();
    }


La classe Pizza.Builder è un tipo generico che utilizza una limitazione di tipo ricorsiva e, grazie al metodo astratto self(), supporta la concatenazione di metodi senza dover eseguire alcuna conversione di tipo nelle sottoclassi. Nelle sottoclassi, è sufficiente impostare il valore restituito di questo metodo astratto su se stesso.

Esaminiamo ora le sottoclassi di Pizza, la pizza di New York e la pizza Calzone, per sperimentare la flessibilità del modello Builder.


public class NyPizza extends Pizza {

    public enum Size {
        SMALL, MEDIUM, LARGE
    }

    private final Size size; // Parametro obbligatorio

    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; // Parametro facoltativo

    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;
        }
    }


Il metodo build() definito dai builder di ciascuna sottoclasse restituisce la sottoclasse concreta. La capacità di un metodo di una sottoclasse di restituire un tipo che non è il tipo restituito dal metodo della superclasse, ma un suo sottotipo, è chiamata tipizzazione covariante dei valori restituiti. Grazie a questa funzione, il client non deve eseguire conversioni di tipo.


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

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


Dal punto di vista del client, è possibile utilizzare l'enumerazione di Pizza e l'enumerazione di ciascuna sottoclasse in modo combinato e completare l'oggetto utilizzando i metodi appropriati di ciascuna.


Svantaggi del modello Builder

  • È necessario creare un oggetto Builder.
  • Il codice può essere prolisso.


Riassunto

Se i costruttori o i metodi di factory statici devono gestire un gran numero di parametri, prendi in considerazione il modello Builder.


Fonte

  • Java Efficace
제이온
제이온
제이온
제이온
[Effective Java] Item 1. Consider static factory methods instead of constructors I metodi di fabbrica statici sono un modo flessibile ed efficiente per creare istanze invece di costruttori. Possono avere un nome, restituire istanze che soddisfano determinate condizioni e migliorare le prestazioni tramite il caching. A differenza del m

27 aprile 2024

[Effettivi Java] Elemento 5. Non dichiarare risorse, utilizzare l'iniezione di dipendenze Se una classe dipende da risorse esterne, è meglio non utilizzare classi di utilità statiche o singleton. L'iniezione di dipendenze può migliorare la flessibilità, la riusabilità e la facilità di test della classe, e l'utilizzo del pattern di metodo di fa

28 aprile 2024

[Effective Java] Item 4. Utilizzare un costruttore privato per impedire l'istanziamento Per le classi di utilità che includono solo metodi e campi statici, è consigliabile impostare l'accesso al costruttore su privato per impedire l'istanziamento. Ciò impedisce agli utenti di creare istanze della classe in modo errato, in quanto si basano su

28 aprile 2024

[Non specialisti, sopravvivere come sviluppatori] 14. Riepilogo dei contenuti del colloquio tecnico per sviluppatori junior Questa è una guida alla preparazione ai colloqui tecnici per sviluppatori junior. Copre argomenti come la memoria principale, le strutture dati, RDBMS e NoSQL, programmazione procedurale e orientata agli oggetti, override e overload, algoritmi di sostituz
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 aprile 2024

Perché non è necessario progettare un sito web reattivo Se desideri creare un sito web ottimizzato per dispositivi mobili, prova Littlely. Littlely è una piattaforma di creazione di siti web che supporta la creazione di siti web in un unico ambiente, adattandoli a desktop, tablet e dispositivi mobili, senza la
리틀리 블로그|올인원 프로필 링크
리틀리 블로그|올인원 프로필 링크
리틀리 블로그|올인원 프로필 링크
리틀리 블로그|올인원 프로필 링크
리틀리 블로그|올인원 프로필 링크

29 maggio 2024

[Non tecnico, sopravvivi come sviluppatore] 13. Colloquio tecnico per sviluppatori junior Presentiamo 7 domande frequenti durante i colloqui tecnici per sviluppatori junior e suggerimenti su come prepararsi al colloquio. Scopri le domande e le strategie di risposta in diversi settori come OOP, database, rete, algoritmi. Preparati per un colloq
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

1 aprile 2024

Cos'è lo sviluppo a cascata? Lo sviluppo a cascata è una metodologia di sviluppo software tradizionale che divide il processo di sviluppo in fasi sequenziali: analisi dei requisiti, progettazione, implementazione, test, distribuzione e manutenzione. Questo metodo ha il vantaggio di a
꿈많은청년들
꿈많은청년들
꿈많은청년들
꿈많은청년들
꿈많은청년들

14 maggio 2024

[Non laureati, sopravvivere come sviluppatori] 16. Suggerimenti per la creazione di un portfolio per sviluppatori junior Uno sviluppatore junior (soprattutto se non ha un background tecnico) deve descrivere chiaramente i servizi o le funzionalità sviluppate nel portfolio, oltre alle competenze tecniche. Ad esempio, per un progetto di "Comunità per studenti in cerca di lavor
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 aprile 2024

[Non specializzato, sopravvivi come sviluppatore] 9. Siti adatti a creare un portfolio Introduciamo 3 tipi di siti che sono ideali per gli studenti di corsi finanziati dallo stato o di bootcamp per creare un portfolio per il lavoro. Puoi sviluppare un gruppo di lavoro comunemente utilizzato in azienda, ERP, sistemi interni di risorse umane
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

30 marzo 2024