Modelagem e implementação com TDD e DDD

Esse artigo mostra como evoluir o código-fonte do negócio de forma clara e eficiente com a modelagem e implementação com TDD e DDD.

Fique por dentro
Este artigo é útil por apresentar o TDD como uma técnica de design (estendendo seu enfoque em relação à abordagem tradicional de testes) e como ele pode ser usado em conjunto com os padrões do DDD de forma a construir um modelo de negócios claro, descritivo, extensível e testável.

Neste contexto, será considerado um problema do mundo real – a modelagem de um domínio para um software pessoal de gerenciamento financeiro – com o intuito de demonstrar a aplicação da técnica proposta.

Segundo o livro The Passionate Programmer (Chad Fowler, 2009), uma das características mais importantes de um programador é sua capacidade de entender o negócio da empresa na qual trabalha (vide BOX 1).

Muitos de nós atuam profissionalmente no desenvolvimento de software em empresas que não têm o cerne do seu negócio em TI (como, por exemplo, no setor bancário, de seguros, de petróleo, etc.).

BOX 1. O programador apaixonado e o mercado de trabalho

O livro The Passionate Programmer, escrito em 2009 por Chad Fowler, apresenta um conjunto de ótimos conselhos sobre como trabalhar com software em empresas.

Dentre dicas sobre gerenciamento da própria carreira até sugestões controversas, mas justificáveis (como a importância de ser o pior programador dentre os melhores), o autor oferece um panorama realista sobre o dia a dia daqueles que trabalham com programação de software – e como manter-se apaixonado pela profissão, apesar de tudo.

Leitura recomendada.

Não se trata, contudo, em ser um especialista em negócio (afinal, não é nossa profissão – como programadores, nosso trabalho é criar software), mas é importante que se conheçam os conceitos relevantes ao negócio e como os mesmos se relacionam, de forma a entender as necessidades dos clientes, abrindo caminho para a criação de um produto de software adequado.

Apenas ser especialista em tecnologia, num contexto como este, não basta: o programador deve entender o que o cliente realmente precisa e saber transportar esta necessidade para software.

A questão aqui é comunicação e entendimento. Ao conhecer o negócio da empresa, o programador está mais apto a entender, criticar e questionar requisitos e, posteriormente, a implementar software de valor.

Contudo, sabe-se que a falha de comunicação é um problema comum em desenvolvimento de software: o maior exemplo disto talvez seja aquele onde um mesmo termo é empregado com múltiplos significados (o que leva o dito por uma pessoa a ser entendido diferentemente por outra).

Desconsiderando o problema de comunicação por um momento, ainda resta a questão técnica de escrever software com base em conceitos do negócio. Existem tantas formas de se fazer isto quanto existem programadores – e nem todas as formas empregadas resultam em código-fonte legível, claro, extensível e testável, e que representa claramente o negócio da empresa.

No dia a dia, observa-se que dúvidas sobre as regras de negócio são repassadas para o código-fonte, o que resultará em problemas no futuro.

Por mais que um código-fonte esteja bem escrito, se os conceitos assumidos divergirem dos conceitos do negócio, problemas podem ocorrer por conta de dificuldades de comunicação e entendimento no que se espera que deva ser feito.

Neste contexto, as técnicas de modelagem e implementação que envolvem DDD e TDD podem ser empregadas em conjunto para lidar com os problemas de entendimento de negócio e representação adequada do mesmo em código-fonte Java com qualidade.

Conceituando o TDD enquanto ferramenta de design

A técnica de TDD (Test-Driven Development) é bastante conhecida atualmente pela sua característica controversa de escrever testes antes do código-fonte.

Ao se considerar o percentual de cobertura de código-fonte com testes como uma métrica de qualidade, TDD apresenta-se como uma forma eficaz de se programar.

Contudo, TDD também deve ser relacionado com design de software. O criador da técnica, em seu livro Test-Driven Development By Example (Kent Beck, 2003), aponta que as duas regras básicas do TDD (escrever código novo apenas quando o teste automatizado falhar e eliminar duplicação) levam a duas implicações em design: a) o design surge de forma orgânica, com código em execução provendo feedback entre decisões; e b) o design deve consistir em componentes com baixo acoplamento e alta coesão, para permitir que seja fácil testar.

Um design orgânico é aquele que surge conforme a aplicação evolui.

Este design é chamado de Evolucionário por Martin Fowler, e é caracterizado por ser parte do processo de programação, crescendo enquanto o software é implementado.

Ainda segundo Fowler, este design é um desastre em sua forma comum, pois o que resulta é um conjunto de decisões ad-hoc que tornam o código difícil de manter.

Uma forma de fazer o design evolucionário funcionar é pela utilização de práticas que imponham o design, tais como testes, refatoração e integração contínua – práticas empregadas no método XP.

O TDD é uma técnica a ser utilizada com o design Evolucionário, em contraposição ao design Planejado. Num design Evolucionário em sua forma comum, como já dito anteriormente, pode-se entender que não existe design de fato (todas as decisões são ad-hoc em termos de codificação e não existe uma preocupação com design como um todo), o que leva a um aumento da entropia de software, dificultando evoluções e manutenções. Já um design Planejado é o inverso: sugere que deve haver um planejamento prévio e de alto nível, que considere todas as necessidades de mudanças possíveis, antes mesmo que o software seja desenvolvido.

Ambas as abordagens (planejada e evolucionária) falham em seus objetivos enquanto conceitos isolados em si, quando é considerada a questão da mudança em software. Se a entropia de software causada pelo design Evolucionário dificulta mudanças, também o design Planejado o faz, no sentido de que adota uma postura na qual mudanças não são encorajadas (todo impacto em design deveria ter sido pensado no início do projeto, antes da implementação), ou adota uma postura de flexibilidade total a todo tipo de mudanças, o que torna a fase de design extremamente cara (pois é preciso antecipar todos os problemas que ainda não existem), e pode tornar a implementação pouco clara e eficiente (pois design genérico demais para atender a problemas de forma muito flexível pode demandar implementação pouco performática e difícil de entender e manter). A proposta do método XP é a de utilizar um design Evolucionário de forma controlada, e o TDD é uma das técnicas empregadas para controlar a entropia.

Segundo Kent Beck, “design existe para permitir que mudanças em software sejam realizadas facilmente por um longo tempo”. O software que faz uso de TDD possui componentes criados com alta coesão e baixo acoplamento, pois é resultado do processo que gera código-fonte testável.

Estas características da orientação a objetos que emergem durante a prática de TDD propiciam a facilidade em mudanças sugeridas por Kent. Contudo, caso o TDD seja abandonado, o design pode deteriorar com o tempo, aumentando a entropia e tornando o software mais difícil de manter e corrigir.

Não é verdadeiro afirmar que apenas TDD garante qualidade em design, mas pode-se considerar que a prática do TDD, enquanto baseada na criação de testes automatizados, força a existência de um design de qualidade. " [...] continue lendo...

Artigos relacionados