Статья
Шаблон проектирования "Строитель"

Шаблон проектирования "Строитель"

16 марта 2020

Относится к порождающим шаблонам.

Используем класс-строитель, который сам конструирует объект по шагам, используя различные методы (получаем объекты разной конфигурации).

Плюсы:
- уменьшаем количество аргументов конструктора до 1;
- позволяет создать несколько однотипных объектов, незначительно отличающихся друг от друга;
- изолируем логику создания объектов от самого объекта

Минусы:
- класс привязан к классам строителей


Пример на PHP

class Pizza
{
    private int  $size;
    private bool $cheese = false;
    private bool $pepperoni = false;
    private bool $tomato = false;

    public function __construct(PizzaBuilder $builder)
    {
        $this->size = $builder->getSize();
        $this->cheese = $builder->getCheese();
        $this->pepperoni = $builder->getPepperoni();
        $this->tomato = $builder->getTomato();
    }
}

class PizzaBuilder
{
    private int  $size;
    private bool $cheese = false;
    private bool $pepperoni = false;
    private bool $tomato = false;

    public function __construct(int $size)
    {
        $this->size = $size;
    }

    public function addPepperoni(): PizzaBuilder
    {
        $this->pepperoni = true;

        return $this;
    }

    public function addCheese(): PizzaBuilder
    {
        $this->cheese = true;

        return $this;
    }

    public function addTomato(): PizzaBuilder
    {
        $this->tomato = true;

        return $this;
    }

    public function getSize(): int
    {
        return $this->size;
    }

    public function getPepperoni(): bool
    {
        return $this->pepperoni;
    }

    public function getCheese(): bool
    {
        return $this->cheese;
    }

    public function getTomato(): bool
    {
        return $this->tomato;
    }

    public function build(): Pizza
    {
        return new Pizza($this);
    }
}

Использование:

$pizza = (new PizzaBuilder(30))->addPepperoni()->addTomato()->build();


Пример на Go

package main

type Pizza struct {
   size int
   cheese bool
   pepperoni bool
   tomato bool
}

type PizzaBuilder struct {
   size int
   cheese bool
   pepperoni bool
   tomato bool
}

func NewPizzaBuilder() *PizzaBuilder {
   return &PizzaBuilder{}
}

func (pb *PizzaBuilder) SetSize(size int) {
   pb.size = size
}

func (pb *PizzaBuilder) AddCheese() {
   pb.cheese = true
}

func (pb *PizzaBuilder) AddPepperoni() {
   pb.pepperoni = true
}

func (pb *PizzaBuilder) AddTomato() {
   pb.tomato = true
}

func (pb *PizzaBuilder) Build() Pizza {
   return Pizza{
      size:      pb.size,
      cheese:    pb.cheese,
      pepperoni: pb.pepperoni,
      tomato:    pb.tomato,
   }
}

func main() {
   builder := NewPizzaBuilder()
   builder.SetSize(30)
   builder.AddTomato()
   builder.AddPepperoni()
   builder.Build()
}



Источники:
http://designpatternsphp.readthedocs.io/ru/latest/Creational/Builder/README.html
https://habrahabr.ru/company/mailru/blog/325492/