5
respostas

Padrão Procedural

Achei excelente a explicação de usar objetos em vez de números para representá-los, porém como eu faço de fato para solucionar o problema se na grande maioria das vezes os bancos de dados são relacionais ? Exemplo: provavelmente o estado teria uma chave apontando para a tabela de estados, ou seja, haveria ali um número que impossibilitaria essa implementação passada no vídeo. Se fizermos um join para o trazer o nome do estado, haveria uma série de espaços e acentos nos tipos o que teria que ser tratado. A solução que havia no texto é a melhor solução mesmo para esses casos, mesmo sendo procedural ?

5 respostas

Estados geralmente são coisas bem definidas, raramente se cria um novo estado para uma determinada coisa. Diferente de uma categoria de um produto, o.de frequentemente se cria uma nova.

Nesse caso, por que não dar um id pra cada estado? Se a nossa necessidade é persistir o estado no Banco de Dados, nada mais adequado. Eu geralmente implemento os estados, cada em uma classe como no padrão e ao mesmo tempo eu crio uma tabela e ids para fazer a relação em banco. Uso isso combinado com o padrão Factory pra trazer os dados de volta do banco para a aplicação. O controle de fluxo eu faço dentro das classe dos Estados, mas ao persistir envio os ids.

Esse padrão é realmente conflitante com o uso de bancos relacionais.

Então, vou dar um exemplo: gostaria de criar uma interface avaliação e classes sendo os tipos de avaliação, porém gostaria de na hora de exibir, instanciar a classe correta conforme o id do tipo. Então ficaria cheio de ifs conforme foi dito que não é um bom padrão. Como seria o código mais eficiente pra isso? Pensei em fazer o Chain of Responsability, mas vi aqui uma outra forma no texto da aula do state. Qual o mais adequado pra poder ter fácil manutenção e extensão de novas classes ?

Entendi...Acho que tipo de avaliação não é um estado. É uma espécie de categoria. Nesse caso eu apenas usaria o padrão factory pra instanciar a classe do tipo certo sem um monte de ifs

Você tem razão quanto ao fato de não ser na verdade um estado, entendi. Então se trata mesmo de uma categoria. Agora como saber qual factory ou builder, dependendo da complexidade do objeto, instanciar se o que tenho na verdade são campos numéricos de id ? Existe uma forma "elegante" de resolver isso, ou faço mesmo o chain pra poder verficar qual é a classe correta e então instanciá-la ?

Bom, no banco de dados você tem uma tabela pra guardar o tipo.

1 - TipoDeAvalicacao1 2 - Tipo2DeAvalicacao2

No Select provavelmente terá

SELECT 
    avaliacao.id,
    avaliacao.nome,
    tipo.id,
    tipo.nome --Então voce pode usar o nome aqui
FROM avaliacao 
INNER JOIN tipo ON tipo.id = avaliacao.tipo_id

Agora pra criar o objeto de acordo com o tipo, usando uma factory.

interface TipoDeAvaliacao
{
    public function getId();
    //Outras abstrações aqui
}

class TipoDeAvalicacao1
{
    private $id = 1;

    public function getId()
    {
        return $this->id;
    }

    //Outros Métodos específicos do tipo aqui
}

class TipoDeAvalicacao2
{
    private $id = 2;

    public function getId()
    {
        return $this->id;
    }

    //Outros Métodos específicos do tipo aqui
}

class TipoAvaliacaoFactory()
{
    public function create(  $tipo )
        { 
        if( class_exists( $tipo ) ) 
            return new {$tipo}();
        else
            throw new Exception( "Tipo de Avalicacao $tipo não existe");
    }
}

Bom, mas e na hora de gravar? Provavelmente você também terá um select no HTML onde o usuário seleciona o tipo de prova na hora de gravar ou editar. Você também poderá usar o nome ao invés do id.

//No Select
<select name="tipo_avaliacao">
    <option value="TipodeAvaliacao1">TipodeAvaliacao1</option>
<option value="TipodeAvaliacao2">TipodeAvaliacao2</option>
</select>

E quando receber o post faria

$tipo = $_POST['tipo_avaliacao'];

//Criando a Avaliacao
$avaliacao = new Avalicao();

//Setando o que é preciso..

//Setando o tipo da avaliação
$tipoAvaliacao = (new TipoAvaliacaoFactory())->create($tipo);

$avaliacao->setTipo( $tipoAvaliacao );

Se você acha que pode haver criações e edições de tipos com bastante frequência. Aborte esse negócio de criar uma classe pra cada tipo e deixa tudo no banco, porque se não você vai ter que alterar o código toda vez que alguém quiser criar um tipo novo.