BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Test Driven Development e os Problemas com o Código Legado

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

Favoritos

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

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT