¿Qué es un antipatrón?

193

Estoy estudiando patrones y antipatrones. Tengo una idea clara sobre los patrones, pero no obtengo antipatrones. Las definiciones de la web y Wikipedia me confunden mucho.

¿Alguien puede explicarme en palabras simples qué es un antipatrón? ¿Cuál es el propósito? ¿Qué hacen? ¿Es algo malo o bueno?

g.revolución
fuente
Se considera malo, pero podría ser la única solución. Piensa dos veces y vete.
Константин Ван

Respuestas:

244

Los antipatrones son ciertos patrones en el desarrollo de software que se consideran malas prácticas de programación.

A diferencia de los patrones de diseño que son enfoques comunes de problemas comunes que se han formalizado y generalmente se consideran una buena práctica de desarrollo, los antipatrones son lo contrario y no son deseables.

Por ejemplo, en la programación orientada a objetos, la idea es separar el software en pequeñas piezas llamadas objetos. Un antipatrón en la programación orientada a objetos es un objeto de Dios que realiza muchas funciones que se separarían mejor en diferentes objetos.

Por ejemplo:

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

El ejemplo anterior tiene un objeto que hace todo . En la programación orientada a objetos, sería preferible tener responsabilidades bien definidas para diferentes objetos para mantener el código menos acoplado y, en última instancia, más sostenible:

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

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

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

La conclusión es que hay buenas maneras de desarrollar software con patrones comúnmente utilizados (patrones de diseño ), pero también hay formas en que se desarrolla e implementa el software que puede generar problemas. Los patrones que se consideran malas prácticas de desarrollo de software son antipatrones.

Coobird
fuente
9
¿Hay otros ejemplos de antipatrones además de GodObject?
Tomasz Mularczyk
@Tomasz Programming Pasta sirve es un ejemplo de ello. Se generaliza mejor como una pobre encapsulación entre muchos objetos pequeños. Considérelo lo opuesto al objeto de Dios en.wikipedia.org/wiki/Spaghetti_code
AWrightIV
@Tomasz todo lo que es malo, pero que algunas personas hacen, es un antipatrón. Por ejemplo, try: <do something>; except: passpuede ser el antipatrón Cardinal Sin en Python. Vea esto: realpython.com/blog/python/…
eric
1
¿Se puede considerar un Singleton como un antipatrón porque hace que sea más difícil burlarse y ejecutar pruebas en paralelo (ya que todas las pruebas usan y mutan el mismo singleton, lo que resulta en inconsistencias)?
lostsoul29
63

Cada vez que escucho sobre Anti-patrones, recuerdo otro término, a saber. Olor de diseño.

"Los olores de diseño son ciertas estructuras en el diseño que indican una violación de los principios fundamentales de diseño e impactan negativamente en la calidad del diseño". (De "Refactorización para olores de diseño de software: gestión de la deuda técnica")

Hay muchos olores de diseño clasificados según los principios de diseño que violan:

La abstracción huele

Falta de abstracción: este olor surge cuando se utilizan grupos de datos o cadenas codificadas en lugar de crear una clase o una interfaz.

Abstracción imperativa: este olor surge cuando una operación se convierte en una clase.

Abstracción incompleta: este olor surge cuando una abstracción no admite métodos complementarios o interrelacionados por completo.

Abstracción multifacética: este olor surge cuando una abstracción tiene más de una responsabilidad asignada.

Abstracción innecesaria: este olor se produce cuando una abstracción que realmente no es necesaria (y por lo tanto podría haberse evitado) se introduce en un diseño de software.

Abstracción no utilizada: este olor surge cuando una abstracción se deja sin usar (no se usa directamente o no es accesible).

Abstracción duplicada: este olor surge cuando dos o más abstracciones tienen nombres idénticos o una implementación idéntica o ambas.

Olores de encapsulación

Encapsulación deficiente: este olor ocurre cuando la accesibilidad declarada de uno o más miembros de una abstracción es más permisiva de lo que realmente se requiere.

Encapsulación con fugas: este olor surge cuando una abstracción "expone" o "filtra" detalles de implementación a través de su interfaz pública.

Falta de encapsulación: este olor se produce cuando las variaciones de implementación no están encapsuladas dentro de una abstracción o jerarquía.

Encapsulación no explotada: este olor surge cuando el código del cliente usa verificaciones de tipo explícitas (usando if-else encadenado o declaraciones de cambio que verifican el tipo de objeto) en lugar de explotar la variación en los tipos ya encapsulados dentro de una jerarquía.

Olores de modularización.

Modularización rota: este olor surge cuando los datos y / o métodos que idealmente deberían haberse localizado en una sola abstracción se separan y se extienden a través de múltiples abstracciones.

Modularización insuficiente: este olor surge cuando existe una abstracción que no se ha descompuesto por completo, y una descomposición adicional podría reducir su tamaño, complejidad de implementación o ambas.

Modularización dependiente del ciclo: este olor surge cuando dos o más abstracciones dependen unas de otras directa o indirectamente (creando un acoplamiento estrecho entre las abstracciones).

Modularización tipo hub: este olor surge cuando una abstracción tiene dependencias (tanto entrantes como salientes) con una gran cantidad de otras abstracciones.

La jerarquía huele

Falta de jerarquía: este olor surge cuando un segmento de código usa lógica condicional (generalmente junto con "tipos etiquetados") para gestionar explícitamente la variación en el comportamiento donde una jerarquía podría haberse creado y utilizado para encapsular esas variaciones.

Jerarquía innecesaria: este olor surge cuando toda la jerarquía de herencia es innecesaria, lo que indica que la herencia se ha aplicado innecesariamente para el contexto de diseño particular.

Jerarquía no factorizada: este olor surge cuando hay una duplicación innecesaria entre los tipos en una jerarquía.

Jerarquía amplia: este olor surge cuando una jerarquía de herencia es "demasiado" amplia, lo que indica que pueden faltar tipos intermedios.

Jerarquía especulativa: este olor surge cuando uno o más tipos en una jerarquía se proporcionan de forma especulativa (es decir, en función de necesidades imaginarias en lugar de requisitos reales).

Jerarquía profunda: este olor surge cuando una jerarquía de herencia es "excesivamente" profunda.

Jerarquía rebelde: este olor surge cuando un subtipo rechaza los métodos proporcionados por su (s) supertipo (s).

Jerarquía rota: este olor surge cuando un supertipo y su subtipo conceptualmente no comparten una relación "IS-A" que resulta en una sustituibilidad rota.

Jerarquía multitrayecto: este olor surge cuando un subtipo hereda tanto directa como indirectamente de un supertipo que conduce a rutas de herencia innecesarias en la jerarquía.

Jerarquía cíclica: este olor surge cuando un supertipo en una jerarquía depende de cualquiera de sus subtipos.


La definición y clasificación anteriores se describen en "Refactorización para olores de diseño de software: Gestión de deuda técnica ". Algunos recursos más relevantes se pueden encontrar aquí .

Alex
fuente
41

Un patrón es una idea de cómo resolver un problema de alguna clase. Un antipatrón es una idea de cómo no resolverlo porque implementar esa idea daría como resultado un mal diseño.

Un ejemplo: un "patrón" sería usar una función para reutilizar el código, un "antipatrón" sería usar copiar y pegar para el mismo. Ambos resuelven el mismo problema, pero el uso de una función generalmente conduce a un código más legible y mantenible que copiar y pegar.

diente filoso
fuente
18

Un antipatrón es una forma de no resolver un problema. Pero hay más: también es una forma que se puede ver con frecuencia en los intentos de resolver el problema.

Ralph M. Rickenbach
fuente
13

Si realmente desea estudiar AntiPatterns, obtenga el libro AntiPatterns (ISBN-13: 978-0471197133).

En él, definen "Un AntiPattern es una forma literaria que describe una solución común a un problema que genera consecuencias decididamente negativas".

Por lo tanto, si es una mala práctica de programación pero no una común, limitada a una aplicación, una compañía o un programador, no cumple con la parte "Patrón" de la definición de AntiPattern.

kmarsh
fuente
9

Una forma común de hacer un desastre. Como la clase god / kitchensink (hace todo), por ejemplo.

Robert Gould
fuente
6

Curiosamente, una forma determinada de resolver un problema puede ser tanto un patrón como un antipatrón. Singleton es el mejor ejemplo de esto. Aparecerá en ambos conjuntos de literatura.

Ed Sykes
fuente
6

Un antipatrón es el complemento de un patrón de diseño . Un antipatrón es una solución de plantilla que no debe usar en una situación determinada.

xxmajia
fuente
6

Al igual que con un patrón de diseño , un antipatrón es también una plantilla y una forma repetible de resolver un determinado problema, pero de una manera no óptima e ineficaz.

Darnell
fuente
4

Hoy en día, los investigadores y profesionales de ingeniería de software a menudo usan los términos "antipatrón" y "olor" indistintamente. Sin embargo, conceptualmente no son lo mismo. La entrada de Wikipedia de antipatrón establece que un antipatrón es diferente de una mala práctica o una mala idea por al menos dos factores. Un antipatrón es

"Un proceso, estructura o patrón de acción comúnmente utilizado que, a pesar de que inicialmente parece ser una respuesta adecuada y efectiva a un problema, generalmente tiene más malas consecuencias que resultados beneficiosos".

Indica claramente que se elige un antipatrón en la creencia de que es una buena solución (como patrón) al problema presentado; sin embargo, trae más pasivos que beneficios. Por otro lado, un olor es simplemente una mala práctica que afecta negativamente la calidad de un sistema de software. Por ejemplo, Singleton es un antipatrón y la clase de Dios (o la modularización insuficiente) es un olor de diseño.

Tushar
fuente
2

Los antipatrones son formas comunes en que las personas tienden a programar de manera incorrecta, o al menos de una manera no tan buena.

Roman A. Taycher
fuente
0

Cualquier patrón de diseño que esté haciendo más daño que bien al entorno de desarrollo de software dado se consideraría como antipatrón.

Algunos antipatrones son obvios pero otros no. Por ejemplo, Singleton, aunque muchos lo consideran un buen patrón de diseño antiguo, pero hay otros que no lo hacen.

Puedes consultar la pregunta ¿Qué tienen de malo los singletons? para comprender mejor las diferentes opiniones al respecto.

Himanshu Negi
fuente
En realidad, los antipatrones generalmente no son obvios. Obviamente, los malos patrones de diseño son simplemente malos patrones de diseño. Un antipatrón genuino parece sostenible en la superficie, pero manifiesta problemas más adelante. De hecho, no ser obviamente malo es la distinción que los convierte en un antipatrón en primer lugar.
Hawkeyegold
0

Al igual que en Algorithm, puede lograr la solución utilizando la fuerza bruta, pero debe pagar mucho si la situación se vuelve compleja.

Shailesh kumar
fuente