Ir para conteúdo
ppanetony

Design Pattern Builder - Qual utilidade real?!

Recommended Posts

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?!

 

318277968_designpatternbuilder.png.c0181a9285041cc558e86c163c5e2847.png

 

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 ?!?!

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
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.

Compartilhar este post


Link para o post
Compartilhar em outros sites

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();

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora

  • Conteúdo Similar

    • Por Jefferson andre
      Ola,
       
      Criei uma rotina que eh chamada dentro do html, esta rotina abre um banco de dados e pega os valores de algumas variaveis contendo caminhos para video aulas e entao fecha o banco de dados, ao retornar ao html eu quero usar estas variaveis para abrir videos que estarao sendo demonstrados em forma de links.
       
      A mesma situacao foi resolvida dentro do php com imagens para uma outra situacao mas nao consigo fazer isso para videos, se eu conseguir nao preciso puxar as variaveis para o html.
      <?php
      // fazendo uma conexão com o banco de dados
      include("conexao.php");
      //pesquisa
      $resultado = $arquivo->query("SELECT * FROM divulgacao WHERE ativo = 'S' AND tipo = 'IM'");
      if (false === $resultado) {
          echo mysqli_error();
      }
      $linha=mysqli_fetch_array($resultado);
      $caminho_divulgacao = $linha["caminho"];
       
      //echo "<font face='Arial'><span class='style14'>$caminho_divulgacao</span></font>";
      $exibir = "<img src=".$caminho_divulgacao." /><br />";
      echo $exibir ;
       
      mysqli_close($arquivo);
      ?>
       
      Alguma dica ?
    • Por juliogabryell
      Boa tarde, utilizo um sistema de helpdesk open source  (GLPI), no windows server em um servidor local, queria saber se é possivel fazer um script onde mostrar os tecnicos online ou tecnicos logados, sistema bem parecido que tem tambem no outro sistema de helpdesk que é OcoMon, bem antigo, se alguém tiver uma base de como começar ou me auxiliar obrigado.
    • Por PatrickLutherdeck
      Pessoal to tentando instalar o FFMpeg no meu apache no Windows.
      //php.ini extension=php_ffmpeg.dll Coloquei o 'php_ffmpeg.dll' no 'php/axt'
      e os outros aquivos(exceto o de texto) no 'SysWOW64'
      Alguem sabe onde posso ter errado, dei PHPinfo e não imprimiu que carregou a extensao.
    • Por Yan Gabriel
      Sou muito iniciante em Javascript e é por esse motivo que quero sua opinião à respeito de uma classe Usuário que desenvolvi só para testes.
       
      Primeiramente, uma classe Usuário padrão:
      var User = function(name, email) { var _name = name; var _email = email; this.getName = function() { return _name; }; this.getEmail = function() { return _email; }; this.setName = function(name) { _name = name; return this; }; this.setEmail = function(email) { _email = email; return this; }; }; /* Criando uma instância de User: */ var yan = new User('Yan Gabriel', 'yansilvagabriel@gmail.com'); /* Imprimindo Nome e Email: */ console.log('\nNome: ' + yan.getName() + '\nEmail: ' + yan.getEmail()); /* Mudando Nome e Email: */ yan.setName('Yan Machado').setEmail('yanmachado@gmail.com'); /* Imprimindo Nome e Email: */ console.log('\nNovo Nome: ' + yan.getName() + '\nNovo Email' + yan.getEmail()); Agora a classe Usuário modificada:
      var User = function(name, email) { var _information = { name: name, email: email }; var _get = { name: function() { return _information.name; }, email: function() { return _information.email; } } var _set = { name: function(name) { _information.name = name; return this; }, email: function(email) { _information.email = email; return this; } }; var _publics = { get: _get, set: _set }; return _publics; }; /* Criando uma instância de User: */ var yan = new User('Yan Gabriel', 'yansilvagabriel@gmail.com'); /* Imprimindo Nome e Email: */ console.log('\nNome: ' + yan.get.name() + '\nEmail: ' + yan.get.email()); /* Alterando Nome e Email: */ yan.set.name('Yan Machado').email('yanmachado@gmail.com'); /* Imprimindo Nome e Email: */ console.log('\nNome: ' + yan.get.name() + '\nEmail: ' + yan.get.email()); É evidente o maior número de linhas escritas, mas sua manutenção assim como a utilização de seus métodos parece mais fácil.
      Em contra partida creio que, criando objetos literais dentro de objetos literais, estou aumentando o processamento desnecessário dessas informações. O que vocês acham?
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.