InfoQ

InfoQ

Notícias

Meus Favoritos

Faça oLogin ou Cadastre-se para ativar o recurso de favoritos por tempo ilimitado.

O conteúdo foi adicionado aos favoritos!

Houve um erro ao adicionar aos favoritos! Por favor, tente novamente.

Test Driven Development e os Problemas com o Código Legado

Postado por Mark Levison , traduzido por José Marcelo Santuci em 11 Dez 2009

Seções
Desenvolvimento,
Processos e Práticas,
Arquitetura e Design
Tópicos
Arquitetura ,
Técnicas Ágeis ,
Agile ,
Programação
Tags
TDD ,
Testes ,
Código Legado

Complex MazeAllan Baljeu estava aplicando TDD em uma base de código legado C++ e estava em apuros porque:

nós encontramos classes que não implementam integralmente a funcionalidade que é eventualmente necessária, e quando outros querem usar essas classes, e, eventualmente, as implementações mais completas são necessárias, verificamos que o projeto original não é suficiente, um novo projeto é necessário, alguns testes precisam mudar e consequentemente os usos anteriores das classes atualizados.

Ele questionou se Big Design Up Front ajudaria a resolver o problema. George Dinwiddie, Agile Coach, sugeriu que o projeto de Alan estava tentando lhe dizer algo. Você tem que prestar a atenção aos fundamentos do código limpo. Olhe para fundamentos básicos, acoplamento e coesão (ou seja, SOLID Code).

Mike “Geepaw” Hill, Agile Coach, diz que em seus anos de treinador de equipes ágeis, um dos seguintes itens tem sido a raiz destes problemas:

  • a equipe ainda não faz refactoring na velocidade máxima, então as classes não são realmente
    mínimas
  • a equipe ainda não está qualificada a simplicidade, idem acima
  • a equipe ainda não está fazendo microteste (também conhecido comoteste unitário) agressivo e rápido, portanto as mudanças quebram os testes muitas vezes
  • a equipe não sabe lidar com outras equipes ou com dependências públicas, por exemplo, API enviadas
  • a equipe não programa em par e nem possui um espaço de trabalho aberto, diminuindo drasticamente o entendimento de toda equipe.
  • a equipe provavelmente não tem compilações estáveis
  • a equipe pode estar usando ferramentas dos anos 40

Keith Ray, XP Coach, sugere que, com código legado (isto é, sistemas com alta dívida técnica) o custo da regularização da dívida técnica domina o custo de implementação de uma história. Então, ele sugere uma abordagem:

Para tornar o código mais bem construído (pagando as dívidas técnicas), quando você precisar incorporar uma nova característica, você deve prestar muita atenção nos code smells (sintomas no código fonte que possivelmente indicam um problema), tanto no novo código quanto nos antigos e considerar o refactoring para lidar com cada code smell a medida que você os reconhece.

Você pode fazer refactorings manualmente em pequenos passos seguros (mesmo em C++). Siga atentamente as instruções do livro de Fowler sobre Refactoring até memorizá-las. O Eclipse com o gcc tem alguns refactorings que realmente funcionam: Extract Method e Rename. Rename considera o escopo, por isso é mais seguro do que procura e substituição. Extract Method e os outros refactorings do Ecipse podem apresentar falhas, então tenha cuidado ao usá-los. Para coisas como mudar a assinatura de um função, "deixe o compilador" mostrar onde as mudanças têm de ser feitas.

Você também precisa de testes para garantir que os refactorings não prejudiquem as funcionalidades existentes. O livro do Feather trabalhando com código legado tem muitas técnicas para adicionar testes ao código legado. Em um nível mais elevado, os code smells são violações de princípios de bom projeto. Por exemplo, o princípio da responsabilidade única (SRP - Single Responsibility Principle) diz que deve haver um propósito para cada classe / método / módulo. Existem princípios sobre acoplamento e coesão, gerenciamento de dependência, etc. Muitas vezes é mais fácil detectar um code smell do que aplicar esses princípios abstratos. "Large Class" e "Large Method" são compensados pelo "Extract Class" e "Extract Method / Move Method", mesmo sabendo que o SRP ajuda na decisão de que partes de uma classe ou método deve ser extraído.

Talvez o princípio de projeto mais importante é o "Diga, não pergunte": mantenha a funcionalidade e os dados juntos .... código ruim, muitas vezes tem a mesma funcionalidade em um só lugar, e obtém os dados de que necessita de outros lugares, criando problemas com dependências e a falta de localização - o efeito é "ao adicionar uma funcionalidade muitas mudanças em muito código são necessárias". Os code smells "Shotgun Surgery", "Feature Envy", "Long Parameter List" são aplicáveis aqui.

Obter um retorno rápido irá permitir mais refactorins, o que irá (finalmente) permitir um desenvolvimento mais rápido de novas funcionalidades. Tente fazer acontecer a compilação paralela (compilação distribuída). Tente obter arquivos fontes e de header menores. Reduza a complexidade dos arquivos de header - use declarações forward, evite código inline e tente manter apenas uma classe por arquivo de hearder / arquivo fonte. Usando amplamente o idioma "Pimpl" pode diminuir o tempo de compilação em 10%, mas pode também disfarçar o "Large Class" e "Feature Envy" code smells. A vantagem do refactoring ao invés de reescrever, é que você sempre tem código funcionando. Se os testes manuais e automatizados são bons, então você deve ser capaz de entregar o código, mesmo que seja um caminho intermediário entre um projeto mau e um bom projeto.

Keith também escreveu “Refactoring: Small Steps Guaranteed to Help You Clean Up Your Code” um artigo sobre refactoring de código C++ na revista Better Software.

Anteriormente no InfoQ: Dealing with Legacy Code, Uncle Bob e a Aplicabilidade do TDD e Making TDD Stick: Problems and Solutions for Adopters

Conteúdo Educacional

Formando equipes de alto desempenho, parte 1: Início e fases de evolução

Nesta primeira parte de uma série sobre equipes de alto desempenho e gerenciamento Agile, veja uma introdução geral e uma apresentação dos estágios de formação das equipes.

Business Model Canvas, passo a passo

O Business Model Canvas é uma ferramenta estratégica para a construção visual de novos produtos ou serviços. Conheça cada um dos seus elementos e como preencher o Canvas, passo a passo.

Google Apps Script, Parte 2: Google Docs, triggers e envio de emails

Nessa segunda e última parte de uma série sobre o Google Apps Script, conheça como funciona o envio de emails, a conversão de documentos e como criar menus e triggers.

Serviços de cloud computing PaaS: um guia para desenvolvedores Java

Este artigo avalia seis dos mais importantes fornecedores de serviços de cloud computing PaaS para desenvolvedores Java, analisando critérios como desempenho, escalabilidade e tecnologias suportadas.

Canvas de Modelo de Negócios: uma contribuição para o sucesso de Startups

O Canvas de Modelo de Negócios é um novo modo de comunicar e suportar a validação iterativa, incremental e empírica de modelos de negócio de startups e novos produtos substituindo o plano de negócios.

Entrevista com Rebecca Parsons Parte 2: Agile Distribuído, Arquitetura vs. Design e SOA

Nesta segunda e última parte de uma entrevista exclusiva para InfoQ Brasil, Rebecca Parsons, CTO da ThoughtWorks, fala sobre o Agile Distribuído e técnicas para definição de arquiteturas.

Entrevista com Rebecca Parsons Parte 1: Agile nas Empresas e Arquitetura Evolucionária

Nessa primeira parte de uma entrevista com a CTO da ThoughtWorks, veja recomendações sobre formas de construir e arquitetar sistemas para obter o máximo de flexibilidade e responsividade a mudanças.

Agile das equipes à organização: o papel do gerente, estratégias e dicas para a adoção

Os gerentes de projetos podem assumir o papel crítico de liderar a introdução do Agile. Vejas conceitos, dicas e técnicas para apoiar esse processo de mudanças.