O que é um anti-padrão?

193

Estou estudando padrões e antipadrões. Tenho uma ideia clara sobre padrões, mas não recebo anti-padrões. Definições da web e da Wikipedia me confundem bastante.

Alguém pode me explicar em palavras simples o que é um anti-padrão? Qual é o propósito? O que eles fazem? É uma coisa ruim ou boa?

g.revolution
fonte
É considerado ruim, mas pode ser a única solução. Pense duas vezes e vá embora.
Константин Ван

Respostas:

244

Antipadrões são certos padrões no desenvolvimento de software que são considerados más práticas de programação.

Ao contrário dos padrões de design que são abordagens comuns para problemas comuns que foram formalizados e geralmente considerados uma boa prática de desenvolvimento, os antipadrões são o oposto e são indesejáveis.

Por exemplo, na programação orientada a objetos, a idéia é separar o software em pequenos pedaços chamados objetos. Um antipadrão na programação orientada a objetos é um objeto de Deus que executa muitas funções que seriam melhor separadas em objetos diferentes.

Por exemplo:

class GodObject {
    function PerformInitialization() {}
    function ReadFromFile() {}
    function WriteToFile() {}
    function DisplayToScreen() {}
    function PerformCalculation() {}
    function ValidateInput() {}
    // and so on... //
}

O exemplo acima tem um objeto que faz tudo . Na programação orientada a objetos, seria preferível ter responsabilidades bem definidas para diferentes objetos para manter o código menos acoplado e, em última análise, mais sustentável:

class FileInputOutput {
    function ReadFromFile() {}
    function WriteToFile() {}
}

class UserInputOutput {
    function DisplayToScreen() {}
    function ValidateInput() {}
}

class Logic {
    function PerformInitialization() {}
    function PerformCalculation() {}
}

A linha inferior é que existem boas maneiras de desenvolver software com padrões comumente usados ​​(padrões de design ), mas também existem maneiras de desenvolver e implementar software que podem levar a problemas. Padrões considerados más práticas de desenvolvimento de software são antipadrões.

coobird
fonte
9
algum outro exemplo de anti-padrões ao lado de GodObject?
Tomasz Mularczyk
A programação do Tomasz Pasta serve é um exemplo. É melhor generalizado como um encapsulamento ruim entre muitos objetos pequenos. Considere o oposto do objeto de Deus en.wikipedia.org/wiki/Spaghetti_code
AWrightIV
Tomasz @ qualquer coisa que é ruim, mas é feita por algumas pessoas, é um antipadrão. Por exemplo, try: <do something>; except: passpode ser o antipadrão do Cardinal Sin em Python. Veja isto: realpython.com/blog/python/…
eric
1
Um Singleton pode ser considerado um antipadrão porque torna mais difícil zombar e executar testes em paralelo (já que todos os testes usam e modificam o mesmo singleton, resultando em inconsistências)?
lostsoul29
63

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 .

Alex
fonte
41

Um padrão é uma ideia de como resolver um problema de alguma classe. Um antipadrão é uma idéia de como não resolvê-lo, porque a implementação dessa idéia resultaria em um design inadequado.

Um exemplo: um "padrão" seria usar uma função para reutilização de código, um "anti-padrão" seria usar copiar e colar para o mesmo. Ambos resolvem o mesmo problema, mas o uso de uma função geralmente leva a um código mais legível e sustentável do que copiar e colar.

dente afiado
fonte
18

Um anti-padrão é uma maneira de não resolver um problema. Mas há mais: também é uma maneira que pode ser vista com frequência nas tentativas de resolver o problema.

Ralph M. Rickenbach
fonte
13

Se você realmente deseja estudar os AntiPatterns, obtenha o livro AntiPatterns (ISBN-13: 978-0471197133).

Nele, eles definem "Um AntiPattern é uma forma literária que descreve uma solução comum para um problema que gera conseqüências decididamente negativas".

Portanto, se é uma prática de programação ruim, mas não comum - limitada a um aplicativo, uma empresa ou um programador, ela não atende à parte "Padrão" da definição do AntiPattern.

kmarsh
fonte
9

Uma maneira comum de fazer uma bagunça. Como a classe god / kitchensink (faz tudo), por exemplo.

Robert Gould
fonte
6

Curiosamente, uma determinada maneira de resolver um problema pode ser um padrão e um antipadrão. Singleton é o principal exemplo disso. Aparecerá nos dois conjuntos de literatura.

Ed Sykes
fonte
6

Um antipadrão é o complemento de um padrão de design . Um antipadrão é uma solução de modelo que você não deve usar em uma determinada situação.

xxmajia
fonte
6

Assim como em um padrão de design , um antipadrão também é um modelo e uma maneira repetível de resolver um determinado problema, mas de uma maneira não ideal e ineficaz.

Darnell
fonte
4

Hoje, pesquisadores e profissionais de engenharia de software costumam usar os termos "antipadrão" e "cheiro" de forma intercambiável. No entanto, eles não são conceitualmente iguais. A entrada de antipadrão da Wikipedia afirma que um antipadrão é diferente de uma prática ruim ou de uma má idéia por pelo menos dois fatores. Um anti-padrão é

"Um processo, estrutura ou padrão de ação comumente usado que, apesar de parecer inicialmente uma resposta apropriada e eficaz a um problema, normalmente tem mais consequências ruins do que resultados benéficos".

Indica claramente que um antipadrão é escolhido na crença de que é uma boa solução (como padrão) para o problema apresentado; no entanto, traz mais passivos do que benefícios. Por outro lado, um cheiro é simplesmente uma má prática que afeta negativamente a qualidade de um sistema de software. Por exemplo, Singleton é um antipadrão e a classe Deus (ou Modularização Insuficiente) é um cheiro de design.

Tushar
fonte
2

Antipadrões são maneiras comuns pelas quais as pessoas tendem a programar da maneira errada, ou pelo menos da maneira não tão boa.

Roman A. Taycher
fonte
0

Qualquer padrão de design que esteja fazendo mais mal do que bem ao ambiente de desenvolvimento de software fornecido será considerado antipadrão.

Alguns anti-padrões são óbvios, mas outros não. Por exemplo, Singleton, embora muitos o considerem um bom padrão de design antigo, mas há outros que não o consideram.

Você pode verificar a pergunta O que há de tão ruim nos singletons? para entender melhor as diferentes opiniões sobre ele.

Himanshu Negi
fonte
Na verdade, os antipadrões geralmente não são óbvios. Obviamente, padrões de design ruins são simplesmente padrões de design ruins. Um anti-padrão genuíno parece sustentável na superfície, mas manifesta problemas mais tarde. De fato, não ser obviamente ruim é a distinção que os torna um anti-padrão em primeiro lugar.
21418 hawkeyegold
0

Como no algoritmo, você pode obter a solução usando a força bruta, mas precisa pagar muito se a situação se tornar complexa.

Shailesh kumar
fonte