Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Pattern builder - construtor

No exemplo que foi dado sobre builder, nao ficou claro sua utilidade, pois eu poderia descartar o builder do exemplo e utilizar o meio convencional, criando a classe e ao inves de utilizar o construtor pa setar parâmetros eu utilizaria os proprios atributos e metodos dessa classe. Na minha visao deixando de usar o construtor resolveria o problema. Teria um exemplo melhor do builder?

1 resposta
solução!

Olá Willian,

a grande vantagem do Builder, principalmente quando se trata de teste, vem muito da questão de melhorar a semântica e fazer o teste intereferir o menos possível na lógica de negócio.

Por exemplo, se formos fazer o mesmo código do curso usando as propriedades, ficaria assim:

   NotaFiscal nota = new NotaFiscal();
    nota.RazaoSocial = "Caelum";
    nota.Cnpj = "123.456.789/0001-10";
    IList<ItemDaNota> itens = new List<ItemDaNota>();
    itens.Add(new ItemDaNota("item 1", 100.0));
    itens.Add(new ItemDaNota("item 2", 200.0));
    itens.Add(new ItemDaNota("item 3", 300.0));
    nota.Itens = itens;
    nota.Observacoes = "entregar nf pessoalmente";
    nota.DataDeEmissao = DateTime.Now;

E ficaria algo similar a isto usando métodos, que foi a outra solução que você comentou. Só moveria algumas destas lógicas para a classe NotaFiscal.

No caso com o Builder, o código ficou assim:

    NotaFiscal nf = new NotaFiscalBuilder().ParaEmpresa("Caelum").ComCnpj("123.456.789/0001-10").ComItem(new Item("item 1", 100.0))
                          .ComItem(new Item("item 2", 200.0)).ComItem(new Item("item 3", 300.0)).ComObservacoes("entregar nf pessoalmente")
                          .NaDataAtual().Constroi();

Semanticamente, conforme você lê o código desta versão com o Builder parece que você está lendo um texto normal e não código de programação. Parece que é dito "Me faz uma Nota fiscal para a empresa Caelum com Cpnj 123.456.789/0001-10 etc". Principalmente para pessoas que estão entrando/começando no projeto acaba sendo mais fácil de ler um código semântico do que um monte de chamadas de propriedades.

Além disso, quando falamos de testes é comum termos diferentes cases/métodos de teste, cada um testando um cenário específico. E cada um dos testes teria que criar uma Nota Fiscal e preencher as propriedades com valores fazem sentido. Seria basicamente repetir aquele primeiro bloco lá de cima várias vezes, mudando as vezes o valor de 1 parâmetro de um cenário para o outro. Uma opção seria criar um construtor ou método na classe NotaFiscal que insere alguns valores default e em cada cenário você apenas troca os parâmetros que fazem sentido mexer para aquele cenário. Mas ai estaríamos interferindo na regra de negócio para facilitar a vida nas classes de teste. Com o Builder, no próprio construtor do NotaFiscalBuilder podemos já definir estes valores default que servem para os testes. Por exemplo, se este construtor já assume valores default e precisarmos fazer um teste em que o cenário precisa apenas da informação RazaoSocial, poderíamos criar o objeto assim:

    NotaFiscal nfCaelum = new NotaFiscalBuilder() // aqui já coloca um valor default em RazaoSocial, Cnpj, Itens, Observacoes, etc
                .ParaEmpresa("Caelum") //troca apenas o específico para o cenário teste
                .Constroi();

A linha continua parecendo um texto semanticamente falando e não alteramos a regra de negócio para ser usada apenas no teste, mexemos apenas nas classes Builders destinadas para os testes..