sexta-feira, 27 de novembro de 2009

Guicifique seus Testes - Parte 5

Esta é quinta parte da tradução para português do interessante artigo Guicing Up Your Testing, June 21, 2007, por Dick Wall. Trata-se de uma leitura interessante, que junta dois tópicos que estou estudando atualmente: Teste Unitário e Google Guice, além de falar um pouco sobre Injeção de Dependências e os Padrões de Projeto Singleton e Factory.

Índice

Não há bala de Prata

Na quarta parte desta série, precisamos refatorar a classe Pedido para que ela recebesse via construtor um objeto GerenciadorTaxaJuros. Esta medida foi necessária para que o Guice pudesse realizar a injeção de dependências via construtor. Porém, como criação de objetos Pedido agora seriam controlados pelo Guice, perdemos a liberdade de fornecer ao Pedido, via construtor, o objeto Cliente com quem ele se relaciona.

Podemos ponderar se o próprio objeto cliente poderia ter sido injetado pelo Guice, mas isso não se aplica neste caso: precisamos ter a liberdade de criar pedidos para diferentes clientes (ainda neste teste, poderíamos também incluir a checagem da taxa para um segundo cliente!), portanto a informação encapsulada pela classe Cliente está fora dos limites da classe Pedido.

Usar um método setter é a forma mais prática de contornar o problema, mas venhamos e convenhamos, ela é sub-ótima. Talvez o maior problema esteja na perda de mutabilidade: um objeto pedido existente pode ter seu cliente alterado, o que não soa particularmente seguro. Olhando por este prisma, não é desejável permitirmos que o cliente mude após ele ser atribuído ao pedido.

Poderíamos incluir código condicional dentro do setter, por exemplo lançando uma exceção em caso de tentativa de alteração, mas vamos encarar: isto começa a cheirar novamente a bacalhau.

Outro risco de permitir a mutabilidade é que alguém pode agora criar um pedido e esquecer de informar o cliente. O código (deliberadamente) não está mais protegido desta circunstância, podendo falhar com uma exceção do tipo NullPointerException ao se tentar calcular o total do pedido sem ter especificado o cliente deste pedido.

Ao me deparar com o problema da mutabilidade, isso me bloqueou por algum tempo. Certamente isso degradou aquilo que era um exemplo simples e claro em algo não tão limpo. À medida que refletia sobre isso, porém, percebi que este problema tinha valor em si!

Ele trouxe à tona um ponto importante: apesar de que a injeção de dependências seja uma ferramenta fantástica para melhorar o estilo e a modelagem de código, ela não é uma bala de prata. Da mesma forma como muitas outras ferramentas que o precederam, o Guice é surpreendentemente útil e hábil, mas não é a resposta para todos os problemas (nem mesmo para a maioria dos problemas).

Eu realmente gosto de bibliotecas que não tentam ser a solução definitiva, ao invés disso elas fazem algo específico, se propondo a fazer este algo realmente bem feito. Neste ponto, o Guice é muito bem sucedido: é a solução perfeita para Injeção de Dependências em Java: é leve, simples e rápido.

Por outro lado, mesmo um exemplo de teste bem simples evidencia algumas de suas limitações. Tão logo perdemos o controle da criação do Pedido, ao delegar este controle para o Guice, perdemos também o controle sobre a imutabilidade do atributo Cliente da classe Pedido.

Deve estar evidente que delegar ao Guice a criação direta de objetos Pedido foi uma decisão incorreta de modelagem. O problema de setar o cliente para um pedido merece uma boa solução, porém esta solução virá de um ângulo diferente daquele que nos é oferecido pela injeção de dependências. Ao invés disso, podemos mesclar esta abordagem com um outro Padrão de Projeto: Fábrica (Factory Design Pattern).

Nenhum comentário:

Postar um comentário