O que é Anti-Pattern?
Autor: Fabrício Olmo Aride | Publicado: 2010-10-09T17:03:00-03:00

Este texto é uma tradução da WikipediaEm Engenharia de Software, um anti-pattern é um pattern que pode ser utilizado, mas é ineficiente e contraprodutivo na prática.O termo foi cunhado em 1995 por Andrew Koening, inspirado no livro Design Patterns da Gang of Four, que desenvolveu o conceito de design patterns na área de software.O termo foi popularizado três anos depois pelo livro AntiPatterns, que estendeu o uso do termo além das fronteiras do design de software para a interação social geral. De acordo com os autores, devem haver pelo menos dois elementos-chaves presentes para distinguir formalmente um anti-pattern de um simples mau hábito, má prática, ou má idéia:- Alguns patterns repetidos de ação, processo ou estrutura que inicialmente parecem ser benéficos, mas acabam produzindo mais conseqüências ruins que que resultados benéficos;- Uma solução refatorada é claramente documentada, comprovada na prática e repetível.Muitas idéias anti-patterns são mais que erros, retórica, problemas sem solução ou práticas ruins que devem ser evitadas. O uso informal do termo, às vezes denominado "armadilhas" (pitfalls) ou "patterns negros" (dark patterns), refere-se a soluções ruins para os problemas. Desta forma, muitos anti-patterns colocados sob debate não seriam formalmente considerados anti-patterns.Através da descrição formal de erros repetidos, podem-se reconhecer as forças que levam a esta repetição e aprender refatorar este pattern.Anti-patterns Organizacionais:- Paralisia na análise: colocar um esforço desproporcional na fase de análise de um projeto.- Vaca leiteira: Um produto legado rentável que muitas vezes leva à complacência sobre os novos produtos.- Design por commitê: resultado de muitos contribuintes para o design, mas sem uma visão unificada.- Escalação de compromisso: falha em revogar uma decisão quando a mesma se revela errada.- Gestão por perkele (sem tradução): estilo autoritário de gerenciamento, sem tolerância à dissidência.- Gestão matricial: estrutura organizacional sem foco, que resulta em subordinação dividida e falta de direção.- Risco moral: isentar um tomador de decisão das conseqüências de sua decisão.- Gestão Cogumelo: manter funcionários sem informação ou mal informados.- Stovepipe ou Silos (sem tradução): uma estrutura que suporta principalmente o fluxo vertical (de cima para baixo) de informação, mas inibe a comunicação organizacional.- Vendedor bloqueado: tornar um sistema excessivamente dependente de um componente externo.Anti-patterns de Gerenciamento de Projetos:- Marcha para a morte: todos sabem que o projeto caminha para um desastre, exceto o presidente da empresa. Porém, a verdade permanece ocultada e a sobrevida do projeto é mantida artificialmente até que o "Dia D" chega. Definição alternativa de marcha para a morte: funcionários sofrem pressões para trabalharem dias, noites e fins de semana em um projeto com prazo irracional.- Groupthink (pensamento em grupo): durante o groupthink, membros do grupo evitam mencionar pontos de vista que estejam fora da zona de conforto do pensamento consensual.- Fumaça e espelhos: demonstrar como funções não implementadas irão surgir.Software bloat (inchaço do software): permitir versões sucessivas de um sistema a fim de demandar cada vez mais recursos.Anti-patterns de análise:- Apatia do espectador: quando um requisito ou uma decisão de design está incorreta, mas as pessoas que notaram o problema não fazem nada a respeito, porque isto afeta um número maior de pessoas.Anti-patterns do design de Software:- Inversão da Abstração: não expor a funcionalidade implementada requisitada pelos usuários, para que eles a re-implementem usando funções de mais alto nível. - Ponto de vista ambíguo: apresentar um modelo (normalmente análise e design orientados a objeto) sem especificar seu ponto de vista.- Grande bola de lama: um sistema sem nenhuma estrutura reconhecida.- Database-as-IPC: usar um banco de dados como message queue para comunicação de interprocessamento de rotina onde um mecanismo muito mais simples seria apropriado.- Chapeamento a ouro: continuar a trabalhar em uma tarefa ou projeto bem além do ponto em que o esforço extra agrega valor.- Efeito na plataforma interna: um sistema é tão customizável que se torna uma réplica pobre da plataforma de desenvolvimento de software.- Input kludge (sem tradução): falha em especificar e implementar o tratamento de uma entrada possivelmente inválida.- Interface bloat (inchaço da interface): construir uma interface tão poderosa que se torna extremamente difícil de implementá-la.- Magic pushbutton (botão mágico): codificar a lógica de implementação diretamente no código da interface, sem usar abstração.- Race hazard (perigo de corrida): falha na verificação da conseqüência de diferentes ordens de eventos.- Stovepipe system: componentes mal-relacionados e difíceis de manter.Anti-patterns do design orientado a objeto:- Anemic Domain Model: uso do modelo de domínio sem qualquer lógica de negócio. Os objetos do modelo de domínio não podem garantir sua correção, porque sua lógica de validação e mutação está armazenada externamente (muito provavelmente em múltiplos locais).- BaseBean (sem tradução): herdar a funcionalidade de uma classe utilitária em vez de delegar a ela.- Call super (sem tradução): requisitar às subclasses a chamarem um método overriden de uma superclasse.- Problema círculo-elipse: subtipar tipos-variável com base dos subtipos de valor.- Dependência circular: introduzir dependências mútuas diretas ou indiretas entre objetos ou módulos do software.- Constant interface (sem tradução): usar interfaces para definir constantes.- God object (Objeto Deus): concentrar muitas funções em uma única parte do design (classe).- Object cesspool (fossa de objetos): reutilizar objetos cujo estado não está em conformidade com o contrato (possivelmente implícito) para reúso.- Orgia de objetos: falha para encapsular propriamente os objetos, permitindo acesso irrestrito ao seu interior.- Poltergeists: objetos cujo único propósito é passar informação para outro objeto.- Acoplamento seqüencial: uma classe que exige que seus métodos sejam chamados em uma ordem particular.- Problema Iô-Iô: uma estrutura (por exemplo, de herança) que é difícil de entender devido à sua fragmentação excessiva.Anti-patterns de programação:- Complexidade acidental: introduzir uma complexidade desnecessária a uma solução.- Ação a distância: interação inesperada entre partes amplamente separadas de um sistema.- Fé cega: falta de verificação da correção realizada em um bug, ou do resultado de uma subrotina. - Âncora de barco: manter uma parte do sistema que não possui mais qualquer uso.- Busy spin (sem tradução): consumir CPU enquanto aguarda algo ocorrer, normalmente pela verificação repetida em vez de mensagem.- Caching failure (sem tradução): esquecer de resetar uma flag de erro quando o mesmo foi corrigido.- Cargo cult programming (sem tradução): usar patterns e métodos sem entender por quê.- Codificar por exceção: adicionar novo código para tratar cada caso especial reconhecido.- Esconder o erro: fazer um catch da mensagem de erro antes que a mesma seja mostrada ao usuário e não mostrar nada ou uma mensagem sem significado algum.- Hard code: incorporar pressupostos do ambiente de um sistema em sua implementação.- Fluxo de lava: manter código indesejável (redundante ou de baixa qualidade) porque removê-lo é muito caro ou trará conseqüências imprevisíveis.- Seqüência Loop-switch: codificar um conjunto de etapas seqüenciais usando switch dentro de um loop.- Números mágicos: incluir números inexplicáveis em algorítmos.- Strings mágicos: incluir strings literais no código, para comparações, como tipos de eventos etc.- Soft code (código leve): não armazenar a lógica de negócio no código fonte, mas em arquivos de configuração.- Código macarrônico: programas cuja estrutura é difícil de compreender, especialmente por causa da mistura de estruturas de código.Anti-patterns metodológicos:- Copiar e colar um programa: copiar e modificar um código existente em vez de criar soluções genéricas.- Golden hammer (martelo de ouro): presumir que uma solução favorita é universalmente aplicável.- Fator de improbalidade: presumir que seja improvável que um erro conhecido possa ocorrer.- Otimização prematura: codificar pensando somente na eficiência, sacrificando o bom design, manutenibilidade e, muitas vezes, a própria eficiência.- Programar por acidente: tentar chegar a uma solução através de modificações sucessivas no código para ver se funciona.- Reinventar a roda: não adotar uma solução existente e adequada.- Reiventar a roda quadrada: não adotar uma solução existente. Em vez disso, adotar uma solução customizada com um desempenho muito pior que a existente.- Silver bullet (bala de prata): presumir que uma solução técnica favorita pode resolver um processo ou problema maior. - Tester Driven Development (Desenvolvimento Orientado ao Testador): projetos de software onde novos requisitos são especificados em relatórios de erros.Anti-patterns de gerenciamento de configuração:- Dependency hell: problemas com as versões dos produtos exigidos.- DLL hell: gerenciamento inadequado das dynamic-link libraries (DLLs).- Conflito de extensão: problemas com diferentes extensões para as versões do pre-Mac OS da MC OS, na tentativa de corrigir as mesmas partes do sistema operacional. - JAR hell: superutilização de múltiplos arquivos JAR, normalmente causando problemas de versionamento e localização, devido ao não entendimento do Java class loading model.