Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá!
Estou tentando entender a real utilidade do design pattern builder.
Tentei implementar, conforme a imagem e código abaixo.
Não sei se está correta a implementação.
Se não estiver, como eu deveria implementar?!
class Product
{
public function Salvar()
{
echo 'Salvar';
}
}
interface Builder
{
public function buildPart();
}
class ConcreteBuilder implements Builder
{
private $product;
public function buildPart()
{
$this->product = new Product();
}
public function getResult() : Product
{
return $this->product;
}
}
class Director
{
public function construct(Builder $builder)
{
$builder->buildPart();
}
}
Para usar o padrão builder, conforme o código acima, eu faço o seguinte
echo "\n\n";
$director = new Director();
$concreteBuilder = new ConcreteBuilder();
$director->construct($concreteBuilder);
$product = $concreteBuilder->getResult();
$product->Salvar();
Mas, para que todo esses códigos, se eu poderia simplesmente ter o código abaixo que funcionara da mesma maneira?!
$product22 = new Product();
$product22->Salvar();
**Enfim... Qual utilidade real do Design Pattern Builder ?!?!**Obrigado, @Gabriel Heming...
Eu fiz uma nova implementação conforme abaixo...
Também não sei se está certo...
Acho que está...
Não consigo entender o motivo desse padrão...
<?php
//Builder
abstract class BuilderCriadorDeGuerreiro
{
public $guerreiro;
public abstract function ComEspada();
public abstract function ComArmadura();
public abstract function ComArco();
}
//ConcreteBuilder
class ConcreteBuilderCriadorDeGuerreiroFuturista extends BuilderCriadorDeGuerreiro
{
public function __construct()
{
$this->guerreiro = new ProductGuerreiroFuturista();
}
public function ComEspada()
{
$this->guerreiro->EscolherEspada('espada futurista');
}
public function ComArmadura()
{
$this->guerreiro->ColocarArmadura('armadura futurista');
}
public function ComArco()
{
$this->guerreiro->EscolherArco('arco futurista');
}
public function ObterGuerreiro()
{
return $this->guerreiro;
}
}
//ConcreteBuilder
class ConcreteBuilderCriadorDeGuerreiroMedieval extends BuilderCriadorDeGuerreiro
{
public function __construct()
{
$this->guerreiro = new ProductGuerreiroMedieval();
}
public function ComEspada()
{
$this->guerreiro->EscolherEspada('espada medieval');
}
public function ComArmadura()
{
$this->guerreiro->ColocarArmadura('armadura medieval');
}
public function ComArco()
{
$this->guerreiro->EscolherArco('arco medieval');
}
public function ObterGuerreiro()
{
return $this->guerreiro;
}
}
//Director
class DirectorExercito
{
public function ConstruirGuerreiro(BuilderCriadorDeGuerreiro $builderCriadorDeGuerreiro)
{
$builderCriadorDeGuerreiro->ComEspada();
$builderCriadorDeGuerreiro->ComArmadura();
$builderCriadorDeGuerreiro->ComArco();
}
}
//Product
class ProductGuerreiroMedieval extends Guerreiro
{
public function EscolherEspada(string $espada)
{
$this->espada = $espada;
}
public function ColocarArmadura(string $armadura)
{
$this->armadura = $armadura;
}
public function EscolherArco(string $arco)
{
$this->arco = $arco;
}
}
//Product
class ProductGuerreiroFuturista extends Guerreiro
{
public function EscolherEspada(string $espada)
{
$this->espada = $espada;
}
public function ColocarArmadura(string $armadura)
{
$this->armadura = $armadura;
}
public function EscolherArco(string $arco)
{
$this->arco = $arco;
}
}
//Abstract Product
//Não faz parte do Diagrama
//Existe para ter dois tipos de guerreiro
abstract class Guerreiro
{
public $espada;
public $armadura;
public $arco;
public abstract function EscolherEspada(string $espada);
public abstract function ColocarArmadura(string $armadura);
public abstract function EscolherArco(string $arco);
}
class Program
{
private $directorExercito;
private $builderCriadorDeGuerreiro;
private $guerreiro;
public function Main()
{
$this->directorExercito = new DirectorExercito();
$this->builderCriadorDeGuerreiro = new ConcreteBuilderCriadorDeGuerreiroMedieval();
$this->directorExercito->ConstruirGuerreiro($this->builderCriadorDeGuerreiro);
$this->guerreiro = $this->builderCriadorDeGuerreiro->ObterGuerreiro();
echo 'GUERREIRO MEDIEVAL' . "\n";
echo $this->guerreiro->espada . ', ' . $this->guerreiro->armadura . ', ' . $this->guerreiro->arco . "\n\n";
echo 'GUERREIRO FUTURISTA' . "\n";
$this->builderCriadorDeGuerreiro = new ConcreteBuilderCriadorDeGuerreiroFuturista();
$this->directorExercito->ConstruirGuerreiro($this->builderCriadorDeGuerreiro);
$this->guerreiro = $this->builderCriadorDeGuerreiro->ObterGuerreiro();
echo $this->guerreiro->espada . ', ' . $this->guerreiro->armadura . ', ' . $this->guerreiro->arco . "\n\n";
}
}
$program = (new Program())->Main();
>
Citar
The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.
A implementação até está correta, mas não tem sentido nenhum.
O primeiro ponto a entender, é o que realmente é um Design Pattern. A definição mais utiliza é a seguinte: os patterns são soluções reutilizáveis para problemas recorrentes.
Pense no pattern como um molde para resolver um problema em específico, mas, mesmo sendo um molde, ele por si só não se utiliza apenas na base do copy 'n paste. Existe toda uma modelagem/abordagem que deve ser realizada.
No caso do builder, ele serve para separar a criação de um objeto complexo da sua representação. Além disso, poder alterar a representação sem alterar a sua construção.
O uso mais comum que eu vejo do padrão builder é quando você tem uma estrutura de dados e precisa ser representada em diferentes tipos de meios de impressão.
Imagine um site de currículos. Um currículo é uma estrutura complexa de informação sobre a vida profissional de uma pessoa. Dentro deste site, você faz o cadastro do seu currículo e todas as informações são armazenadas no banco de dados. Até aqui, nada de anormal.
Após o currículo preenchido, existem 4 opções de output (representação) do seu currículo:
-
PDF;
-
.DOC/.DOCX;
-
HTML;
-
Texto puro.
Todos sabemos que cada tipo de output (representação) exige uma implementação específica. Entretanto, os dados a serem utilizados (construção) para a representação, são os mesmos. Esse cenário permite a implementação do padrão Builder.
Neste cenário, você implementará um único Director que será responsável pela construção do objeto complexo e, para cada tipo de output/representação, um Builder específico (PDFBuilder, MSWordBuilder, HTMLBuilder, TextBuilder, etc...). Dessa forma, você apenas alterará o builder sem alteração a construção do objeto.