bit_rainbow
@bit_rainbow

Красивый Builder Java?

Прочитал статью
Как по мне она не раскрывает суть панттерна целиком.

Самый последний комент к посту
======
Задач buider решает много, лично я создаю его для следующих целей:

- На вход конструктору подается большое количество объектов, порядок которых легко перепутать

- Я хочу сделать все поля класса неизменяемыми, чтобы немного облегчить себе жизнь в многопоточный среде (в идеале это все поля final)
....
И пример автора не одну из этих задач не решает
======

Лично я использую примерно такой билдер, как вы считаете он качественный ?
Поделитесь своими билдерами.

Мы примерно такие пишем:
package com.oberthur.tsm.ui.model;


import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class MyClass {
    private final boolean enabled;
    private final String login;
    private final String password;


    public static class Builder {
        private boolean enabled = false;
        private String login = "";
        private String password = "";

        public Builder myClass(MyClass myClass) {
            enabled(myClass.getEnabled());
            login(myClass.getLogin());
            password(myClass.getPassword());
            return this;
        }

        public static Builder myClass() {
            return new Builder();
        }

        public Builder enabled(boolean enabled) {
            this.enabled = enabled;
            return this;
        }

        public Builder login(String login) {
            this.login = login;
            return this;
        }

        public Builder password(String password) {
            this.password = password;
            return this;
        }


        public MyClass build() {
            return new MyClass(enabled, login, password);
        }
    }

    @JsonCreator
    public MyClass(
            @JsonProperty("enabled") final boolean enabled,
            @JsonProperty("login") final String login,
            @JsonProperty("password") final String password) {
        this.enabled = enabled;
        this.login = login;
        this.password = password;
    }

    public MyClass() {
        enabled = false;
        login = "";
        password = "";
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public String getLogin() {
        return login;
    }

    public String getPassword() {
        return password;
    }

}
  • Вопрос задан
  • 4170 просмотров
Пригласить эксперта
Ответы на вопрос 1
@asd111
Обычно builder используется там где без builder'a пришлось бы писать много конструкторов для разного набора входных параметров.

Пример из книги Effective Java(автор Joshua Bloch):

Вот пример класса где из за большого количества параметров и из за за их необязательности приходится делать телескопический конструктор
// Telescoping constructor pattern - does not scale well!
public class NutritionFacts {
    private final int servingSize; // (mL)  required
    private final int servings; // (per container) required
    private final int calories; //  optional
    private final int fat; // (g) optional
    private final int sodium; // (mg) optional
    private final int carbohydrate; // (g)   optional
    public NutritionFacts(int servingSize, int servings) {
        this(servingSize, servings, 0);
    }
    public NutritionFacts(int servingSize, int servings,
        int calories) {
        this(servingSize, servings, calories, 0);
    }
    public NutritionFacts(int servingSize, int servings,
    int calories, int fat) {
        this(servingSize, servings, calories, fat, 0);
    }
    public NutritionFacts(int servingSize, int servings,
    int calories, int fat, int sodium) {
        this(servingSize, servings, calories, fat, sodium, 0);
    }
    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;
    }
}


В таких случаях рекомендуется применять builder

// Builder Pattern
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 static class Builder {
        // Required parameters
        private final int servingSize;
        private final int servings;
        // Optional parameters - initialized to default values
        private int calories = 0;
        private int fat = 0;
        private int carbohydrate = 0;
        private int sodium = 0;

        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 carbohydrate(int val)
        { carbohydrate = val; return this; }

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

        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }
    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}


и создавать экземпляр класса так:
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы