Паттерн Builder (Строитель) в Java

Цель паттерна Builder - отделить строительство сложного объекта от его представления, так что один и тот же процесс строительства может создать разные представления.

Паттерн Builder позволяет создавать различные варианты объекта, избегая загрязнения конструктора. Полезно, когда может быть несколько вариантов объекта. Или когда есть много шагов, вовлеченных в создание объекта.

Согласно Википедии: паттерн Builder - это паттерн проектирования программного обеспечения для создания объектов с намерением найти решение для анти-паттерна телескопического конструктора.

Что такое анти-шаблон телескопического конструктора? Рассмотрим на примере:

public Car(String name, Brand brand, Color color, Body body, Wheels wheels, Tuning tuning){}

Как вы можете видеть, количество параметров конструктора может быстро выйти из-под контроля, и это может стать трудным понять расположение параметров. Плюс этот список параметров может продолжать расти, если вы захотите добавить больше опций в будущем. Это называется анти-паттерн телескопическй конструктор.

Разумной альтернативой является использование паттерна Builder. Прежде всего, у нас есть машина (Car), которую мы хотим создать.

public final class Car {
    private final String name;
    private final Color color;
    private final Brand brand;
    private final Body body;
    private final Wheels wheels;
    private final Tuning tuning;

    private Car(Builder builder) {
        this.name = builder.name;
        this.color = builder.color;
        this.brand = builder.brand;
        this.body = builder.body;
        this.wheels = builder.wheels;
        this.tuning = builder.tuning;
    }
}

И тогда у нас есть строитель (builder)

public static class Builder {

    private final Brand brand;
    private final String name;
    private Color color;
    private Body body;
    private Wheels wheels;
    private Tuning tuning;

    /**
     * Constructor
     */
    public Builder(Brand brand, String name) {
        if (brand == null || name == null) {
            throw new IllegalArgumentException("brand and name can not be null");
        }
        this.brand = brand;
        this.name = name;
    }

    public Builder withColor(Color color) {
        this.color = color;
        return this;
    }

    public Builder withBody(Body body) {
        this.body = body;
        return this;
    }

    public Builder withWheels(Wheels wheels) {
        this.wheels = wheels;
        return this;
    }

    public Builder withTuning(Tuning tuning) {
        this.tuning = tuning;
        return this;
    }

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

И тогда его можно использовать как:

Car premiumCar = new Car.Builder(Brand.MERCEDES, "E200")
                .withBody(Body.SEDAN)
                .withColor(Color.WHITE)
                .withTuning(Tuning.WHITE)
                .withWheels(Wheels.SPORTS)
                .build();

Применение

Используйте шаблон Builder, когда

  • алгоритм создания сложного объекта должен быть независим от частей, составляющих объект, и от того, как они собираются
  • процесс строительства должен позволять различные представления для объекта, который построен

Пример на Github

Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки