Шаблон проектирования "Строитель"
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/