Sempre que ouço sobre Anti-padrões, recordo outro termo viz. Design cheiro.
"Os cheiros de design são certas estruturas no design que indicam violação dos princípios fundamentais de design e afetam negativamente a qualidade do design". (De "Refatoração para cheiros de design de software: gerenciamento de dívida técnica")
Existem muitos odores de design classificados com base em violar os princípios de design:
Abstração cheira
Abstração ausente: esse cheiro surge quando grupos de dados ou seqüências de caracteres codificadas são usados em vez de criar uma classe ou uma interface.
Abstração Imperativa: Esse cheiro surge quando uma operação é transformada em classe.
Abstração incompleta: esse cheiro surge quando uma abstração não suporta completamente métodos complementares ou inter-relacionados.
Abstração multifacetada: esse cheiro surge quando uma abstração tem mais de uma responsabilidade atribuída a ele.
Abstração desnecessária: Esse cheiro ocorre quando uma abstração que não é realmente necessária (e, portanto, poderia ter sido evitada) é introduzida em um design de software.
Abstração não utilizada: esse cheiro surge quando uma abstração é deixada sem uso (não diretamente usada ou inacessível).
Abstração duplicada: esse cheiro surge quando duas ou mais abstrações têm nomes idênticos ou implementação idêntica ou ambas.
Cheiros de encapsulamento
Encapsulamento deficiente: esse cheiro ocorre quando a acessibilidade declarada de um ou mais membros de uma abstração é mais permissiva do que realmente necessária.
Encapsulamento com vazamento : esse cheiro surge quando uma abstração "expõe" ou "vaza" detalhes da implementação por meio de sua interface pública.
Encapsulamento ausente: esse cheiro ocorre quando as variações de implementação não são encapsuladas dentro de uma abstração ou hierarquia.
Encapsulamento não explorado: esse cheiro surge quando o código do cliente usa verificações de tipo explícitas (usando instruções if-else encadeadas ou switch que verificam o tipo do objeto) em vez de explorar a variação nos tipos já encapsulados em uma hierarquia.
Cheiros de modularização
Modularização interrompida: esse cheiro surge quando dados e / ou métodos que idealmente deveriam ter sido localizados em uma única abstração são separados e espalhados por várias abstrações.
Modularização insuficiente: esse cheiro surge quando existe uma abstração que não foi completamente decomposta e uma decomposição adicional pode reduzir seu tamanho, complexidade de implementação ou ambos.
Modularização ciclicamente dependente: esse cheiro surge quando duas ou mais abstrações dependem uma da outra direta ou indiretamente (criando um forte acoplamento entre as abstrações).
Modularização tipo hub: esse cheiro surge quando uma abstração tem dependências (de entrada e de saída) com um grande número de outras abstrações.
Cheiros de hierarquia
Hierarquia ausente: esse cheiro surge quando um segmento de código usa lógica condicional (normalmente em conjunto com "tipos de tags") para gerenciar explicitamente a variação no comportamento em que uma hierarquia poderia ter sido criada e usada para encapsular essas variações.
Hierarquia desnecessária: esse cheiro surge quando toda a hierarquia de herança é desnecessária, indicando que a herança foi aplicada desnecessariamente no contexto de design específico.
Hierarquia não fatorada: esse cheiro surge quando há duplicação desnecessária entre os tipos em uma hierarquia.
Hierarquia ampla: esse cheiro surge quando uma hierarquia de herança é "muito" ampla, indicando que tipos intermediários podem estar ausentes.
Hierarquia especulativa: esse cheiro surge quando um ou mais tipos em uma hierarquia são fornecidos especulativamente (ou seja, com base nas necessidades imaginadas e não nos requisitos reais).
Hierarquia Profunda: Esse cheiro surge quando uma hierarquia de herança é "excessivamente" profunda.
Hierarquia rebelde: esse cheiro surge quando um subtipo rejeita os métodos fornecidos pelo (s) seu (s) supertipo (s).
Hierarquia quebrada: esse cheiro surge quando um supertipo e seu subtipo conceitualmente não compartilham um relacionamento "IS-A", resultando em uma substituibilidade quebrada.
Hierarquia de caminhos múltiplos: esse cheiro surge quando um subtipo herda tanto direta quanto indiretamente de um supertipo, levando a caminhos de herança desnecessários na hierarquia.
Hierarquia cíclica: esse cheiro surge quando um supertipo em uma hierarquia depende de qualquer um de seus subtipos.
A definição e classificação acima estão descritas em "Refatoração para cheiros de design de software: Gerenciamento de dívida técnica ". Alguns recursos mais relevantes podem ser encontrados aqui .