Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Estou com dúvida no curso de Design Patterns para bons programadores, no exercício 1 do capítulo Muitos Descontos e o Chain of Responsibility.

Olá. Não sei se entendi muito bem o conceito deste pattern. O número de condições diminui dentro de um método pois é separado em classes, até aí ok... Mas devemos criar N classes e adicionar em cada uma quem será a próxima classe a ser chamada caso não seja atendida determinada condição. O que economizamos em ifs e elses ganhamos neste procedimento acima certo? Se tivermos 10 classes serão instanciadas 10 classes além das adições de quem é a próxima classe em cada uma delas. Duas perguntas em relação a isso : 1 - Esse pattern não deixaria a aplicação com uma pior performance, lógico, dependendo da quantidade e complexidade das condições ? 2 - Não seria melhor que cada classe criada soubesse quem deve ser a próxima a ser chamada, evitando assim muitas linhas de código no mesmo método para instanciar e informar as próximas classes?

4 respostas

O que entendi, neste Design ficaremos com baixo acoplamento e um código de fácil leitura nem sempre usaremos toda a cadeia de uma vez, e se precisar mudar a regra de negocio no futuro ficaria muito mas simples, lembrado que o Design pode ser adaptado as nossas necessidades por isso é muito importante entender o problema que ele pretende resolver.

É verdade. Conseguimos separar bem as responsabilidades de cada método/classe. Com certeza o código pode evoluir muito mais facilmente.

Sobre a performance, acredito que seja aquela a questão de programação procedural versus orientação a objetos. É bem provável que haja um custo de performance com esta solução, mas ela é bem elegante e muito melhor de ser mantida.

Sobre a 2ª questão pensei numa possibilidade de "aliviar a escrita", necessária nas chamadas ao método setProximo(). Podemos receber o próximo desconto no construtor de cada desconto. Porém devemos atentar ao detalhe de que precisaremos instanciar os descontos desejados do último para o primeiro, já que cada desconto precisará do próximo criado no momento de sua criação.

Oi Danilo,

Excelentes perguntas.

A primeira, sobre performance. Geralmente as pessoas perguntam se instanciar classes pra lá e pra cá tornam o sistema mais lento. Hoje em dia, minha resposta é: confie na JVM. Ela vai fazer com que isso seja bastante performático! Então, não escreva código procedural porque acha que ele será mais rápido, ok? Escreva bom código OO!!

Sobre ligar um no outro, lembre-se que você pode mudar a implementação sempre que quiser. Em um padrão, a motivação é a parte mais importante. Nesse capítulo, mostrei pra vocês o Chain of Responsibility da maneira que ele foi descrito pela primeira vez. Eu, quando implemento, faço diferente. Geralmente minha interface tem dois métodos:

boolean aceita();
void executa();

O aceita() me diz se ele deve ser executado. E aí, eu tenho uma List<Acoes> e passo uma por uma vendo se ela deve ser executada. Aí não preciso me preocupar em ficar ligando uma na outra, com aqueles setProximo() que mostrei.

Além disso, como sempre uso algum framework de injeção de dependência, a List<Acoes> é totalmente instanciada pelo framework, então eu não preciso nem sair dando new na mão.

O que acha?

solução!

Não tinha pensado nesta possibilidade melhoraria muito, e nos traria uma facilidade em centralizar as ações em um só lugar muito boa está dica.