Está en la página 1de 7

Un antipatrón de diseño es un patrón de diseño que invariablemente conduce a una mala solución

para un problema.

Al documentarse los antipatrones, además de los patrones de diseño, se dan argumentos a los
diseñadores de sistemas para no escoger malos caminos, partiendo de documentación disponible en
lugar de simplemente la intuición.

El término se origina inspirado en el libro Design Patterns, escrito por un grupo de autores
conocido como Gang of Four, y que aglutina un conjunto de buenas soluciones de programación.
Los autores bautizaron dichas soluciones con el nombre de "patrones de diseño" por analogía con el
mismo término, usado en arquitectura. El libro Anti-Patterns (de William Brown, Raphael Malveau,
Skip McCormick y Tom Mowbray, junto con la más reciente incorporación de Scott Thomas)
describe los antipatrones como la contrapartida natural al estudio de los patrones de diseño. El
estudio formal de errores que se repiten permite reconocer y reconducir los elementos involucrados
hacia una mejor solución. Los antipatrones no se mencionan en el libro original de Design Patterns,
puesto que éste es anterior.

Los antipatrones se consideran una parte importante de una buena práctica de programación. Es
decir, un buen programador procurará evitar los antipatrones siempre que sea posible, lo que
requiere su reconocimiento e identificación tan pronto como sea posible, dentro del ciclo de vida del
software.

El concepto de antipatrón se puede aplicar a la ingeniería en general, e incluso a cualquier tarea


realizada por el hombre. Aunque no se escucha con frecuencia fuera del campo ingenieril, la noción
está ampliamente extendida.

Algunos antipatrones de desarrollo de software

Categoría principal: Antipatrón de diseño

1. Antipatrones de gestión

Productividad a toda costa: La empresa busca la productividad a costa de la calidad del software y
de la calidad de vida de sus empleados, intenta homogeneizar los puestos de trabajo quitando en la
medida de lo posible los permisos a los programadores para que no dañen los sistemas operativos,
monitoriza a los equipos de trabajo y actúa cortando la visibilidad de ciertas páginas o las reuniones
de programadores, al final se consigue que se vaya la gente de la empresa cuando la situación es
insostenible, esto suele ocurrir en ciclos de uno o dos años.

Responsable ausente (absentee manager): Situación en la que el principal responsable o


coordinador se ausenta o permanece en paradero desconocido o no localizable durante importantes
períodos de tiempo.

Todo lo que tienes es un martillo (all you have is a hammer): Gestión gris y plana, incapaz de tratar
a los subordinados de manera personalizada y acorde con sus necesidades particulares.

Negociador de jaula de acero (cage match negotiator): Se aplica cuando un coordinador, gestor o
responsable aplica una filosofía de "éxito a cualquier precio".
Dos caras (doppelganger): Coordinador o compañero que en un determinado momento puede ser
agradable y de trato fácil, pero igualmente puede volverse irracional y despiadado de modo
inesperado.

Rodeos improductivos (fruitless hoops): Gestor o coordinador que solicita grandes cantidades de
datos (en ocasiones sin relevancia alguna) antes de tomar una decisión.

Niñito de oro (golden child): Situación en la que ciertas responsabilidades, oportunidades,


reconocimientos o recompensas van a parar a un determinado miembro del equipo como
consecuencia de una relación personal o en clara contradicción con su rendimiento real.

Pollo sin cabeza (headless chicken): Se aplica al gestor, coordinador o responsable que vive en una
permanente situación de pánico y medidas desesperadas.

Líder pero no gestor (leader not manager): Un buen líder no tiene por qué ser necesariamente un
buen gestor, coordinador o responsable.

Gestión clonada (managerial cloning): Situación en la que los coordinadores o gestores son
contratados e instruidos para actuar y trabajar todos del mismo modo, a imagen y semejanza de sus
propios jefes.

Gestor pero no líder (manager not leader): Un coordinador brillante en sus deberes administrativos
y de gestión, pero que carece de habilidades de liderazgo.

Abuso de la métrica (metric abuse): Utilización manipuladora o incompetente de las medidas y las
métricas.

Sr. Amigo de todos (Mr. Nice Guy): Se aplica al gestor que pretende convertirse en amigo de todos.

Héroe del proletariado (proletariat hero): El "empleado para todo" que siempre es puesto como
ejemplo ante sus compañeros, pero que realmente es la excusa perfecta para demandas crecientes y
constantes incrementos de expectativas.

Estrellas nacientes (rising upstart): Se aplica a quienes, teniendo potencial, no son capaces de
respetar la progresión profesional establecida, y pretenden sortear los plazos y requisitos de
aprendizaje y madurez.

Ejecutivo sin carácter (spineless executive): Gestor, coordinador o responsable que no tiene el
coraje de enfrentarse a las situaciones, asumir las responsabilidades de los errores, o dar la cara por
sus subordinados.

Caballero de tres cabezas (three-headed knight): Gestor indeciso, poco firme, dubitativo.

Arma definitiva (ultimate weapon): Individuos altamente competentes en los que la organización o
sus compañeros confían tanto que se convierten en el canal por el que todo pasa.

Recién llegado (warm body): Trabajador que apenas cubre las expectativas mínimas y por tanto
circula de proyecto en proyecto o de equipo en equipo.
Arquitecto a obrero (super builder): Creencia por la que se asigna a un buen diseñador de software
al desarrollo de código pensando en que tardara mucho menos en teclearlo.

Cantamañanas (singermorning): Gerente que ante el desconocimiento de las aplicaciones que lleva,
y el estado de parcheo imposible de mantener en el que se encuentran, paga los enfados de el cliente
con los programadores que heredaron la aplicación. También se refiere al compañero incompetente
que "succiona" a los demás compañeros.

2. Antipatrones de gestión de proyectos

Humo y espejos (smoke and mirrors): Mostrar cómo será una funcionalidad antes de que esté
implementada.

Mala gestión (bad management): Gestionar un proyecto sin tener suficientes conocimientos sobre la
materia.

Software inflado (software bloat): Permitir que las sucesivas versiones de un sistema exijan cada
vez más recursos.

3. Antipatrones generales de diseño de software

Base de datos como comunicador de procesos (database as an IPC): Usar una base de datos para
comunicar procesos en uno o varios ordenadores, cuando la comunicación entre procesos directa es
más adecuada.

Blob: Véase Objeto todopoderoso.

BOMQ (Batch Over MQ): Abuso en el empleo de integración basada en mensajes en tiempo real
para transferencias esporádicas de gran tamaño en segundo plano.

Clase Gorda: Dotar a una clase con demasiados atributos y/o métodos, haciéndola responsable de la
mayoría de la lógica de negocio.

Botón mágico (magic pushbutton): Tender, desarrollando interfaces, a programar la lógica de


negocio en los métodos de interacción, implementando los resultados de las acciones del usuario en
términos no suficientemente abstractos.

Carrera de obstáculos (race hazard): Incapacidad de prever las consecuencias de diferentes


sucesiones de eventos.

Entrada chapuza (input kludge): No especificar e implementar el manejo de entradas inválidas.

Fábrica de combustible (gas factory): Diseñar de manera innecesariamente compleja.

Gran bola de lodo (big ball of mud): Construir un sistema sin estructura definida.

Interfaz inflada (interface bloat): Pretender que una interfaz sea tan potente que resulta
extremadamente difícil de implementar.
Inversión de abstracción (abstraction inversion): No exponer las funcionalidades implementadas
que los usuarios necesitan, forzando a que se reimplementen a más alto nivel.

Punto de vista ambiguo (ambiguous viewpoint): Presentar un modelo sin concretar ciertos aspectos,
postergando así decisiones conflictivas.

Re-dependencia (re-coupling): Introducir dependencias innecesarias entre objetos.

Sistema de cañerías de calefacción (stovepipe system): Construir un sistema difícilmente


mantenible, ensamblando componentes poco relacionados.

3. 1. Antipatrones de diseño orientado a objetos

Acoplamiento secuencial (sequential coupling): Construir una clase que necesita que sus métodos
se invoquen en un orden determinado.

BaseBean: Heredar funcionalidad de una clase utilidad en lugar de delegar en ella.

Fallo de clase vacía (empty subclass failure): Crear una clase que no supera el test de la subclase
vacía, es decir, que se comporta de manera diferente cuando se invoca desde una subclase que no
añade modificación alguna.

Llamar a super (callsuper): Obligar a las subclases a llamar a un método de la superclase que ha
sido sobrescrito.

Modelo de dominio anémico (anemic domain model): Usar un modelo del dominio sin ninguna
lógica de negocio. Esto no es un enfoque orientado a objetos porque cada objeto debería tener tanto
propiedades como comportamiento asociado.

Objeto sumidero (object cesspool): Reusar objetos no adecuados realmente para el fin que se
persigue.

Objeto todopoderoso (god object): Concentrar demasiada funcionalidad en una única parte del
diseño (clase).

Poltergeist: Emplear objetos cuyo único propósito es pasar la información a terceros objetos.

Problema del círculo-elipse (circle-ellipse problem): Crear variables de tipo pensando en los valores
de posibles subtipos.

Problema del yoyó (yo-yo problem): Construir estructuras (por ejemplo, de herencia) que son
difíciles de comprender debido a su excesiva fragmentación.

Singletonitis: Abuso de la utilización del patrón singleton.

YAFL (yet another layer, y otra capa más): Añadir capas innecesarias a un programa, biblioteca o
framework. Esta tendencia se extendió bastante después de que se publicase el primer libro sobre
patrones.
4. Antipatrones de programación

Nomenclatura heroica (heroic naming): Identificar los miembros de un programa (interfaces, clases,
propiedades, métodos...) con nombres que provocan que el conjunto aparente estandarización con la
ingeniería del software pero que en realidad oculta una implementación anárquica.

Acción a distancia (action at a distance): Provocar la interacción no prevista de componentes muy


distantes de un sistema.

Acumular y arrancar (accumulate and fire): Establecer una colección de variables globales para ser
usadas por un conjunto de subrutinas.

Ancla del barco (boat anchor): Retener partes del sistema que ya no tienen utilidad.

Bucle activo (busy spin): Utilizar espera activa cuando existen alternativas.

Código duro (hard code): Hacer supuestos sobre el entorno del sistema en demasiados lugares de la
implementación.

Complejidad no indispensable (accidental complexity): Dotar de complejidad innecesaria a una


solución.

Código espagueti (spaghetti code): Construir sistemas cuya estructura es difícilmente comprensible,
especialmente debido a la escasa utilización de estructuras de programación.

Código ravioli (ravioli code): Construir sistemas con multitud de objetos muy débilmente
conectados.

Comprobación de tipos en lugar de interfaz (checking type instead of interface): Comprobar que un
objeto es de un tipo concreto cuando lo único que se necesita es verificar si cumple un contrato
determinado.

Confianza ciega (blind faith): Descuidar la comprobación de los resultados que produce una
subrutina, o bien de la efectividad de un parche o solución a un problema.

Doble comprobación de bloqueo (double-checked locking): Comprobar, antes de modificar un


objeto, si es necesario hacer esa modificación, pero sin bloquear para comprobarlo, de manera que
dicha comprobación puede fallar.

Fallo de caché (caching failure): Olvidar restablecer una marca de error cuando éste ya ha sido
tratado.

Lava seca (lava flow): Código muerto e información de diseño olvidada permanecen congelados en
un diseño cambiante. Esto es análogo a un flujo de lava en el que se van endureciendo pedazos de
roca. La solución incluye un proceso de gestión de la configuración que elimina el código muerto y
permite evolucionar o rehacer el diseño para acrecentar la calidad.

Lógica super-booleana (superboolean logic): Emplear comparaciones o abstracciones de la lógica


booleana innecesarias.
Manejo de excepciones (exception handling): Emplear el mecanismo de manejo de excepciones del
lenguaje para implementar la lógica general del programa.

Manejo de excepciones inútil (useless exception handling): Introducir condiciones para evitar que
se produzcan excepciones en tiempo de ejecución, pero lanzar manualmente una excepción si dicha
condición falla.

Momento del código (code momentum) : Establecer demasiadas restricciones sobre una parte del
sistema debido a la asunción de muchas de sus propiedades desde otros lugares del propio sistema.

Números mágicos (magic numbers): Incluir en los algoritmos números concretos sin explicación
aparente.

Ocultación de errores (error hiding): Capturar un error antes de que se muestre al usuario, y
reemplazarlo por un mensaje sin importancia o ningún mensaje en absoluto.

Packratting: Consumir memoria en exceso debido a no liberar objetos reservados dinámicamente


una vez ya han dejado de ser necesarios.

Programación por excepción (coding by exception): Añadir trozos de código para tratar casos
especiales a medida que se identifican.

Secuencia de bucle por casos (Loop-switch sequence): Programar un conjunto de pasos secuenciales
usando un bucle en combinación con una estructura de control por casos.

Cadenas mágicas (magic strings): Incluir cadenas de caracteres determinadas en el código fuente
para hacer comparaciones, como tipos de eventos, etc.

5. Antipatrones metodológicos

Bala de plata (silver bullet): Asumir que nuestra solución técnica favorita puede resolver un
problema mucho mayor.

Desarrollo conducido por quien prueba (tester driven development): Permitir que un proyecto
software avance a base de extraer sus nuevos requisitos de los informes de errores.

Desfactorización (de-factoring): Eliminar funcionalidad y reemplazarla con documentación.

Factor de improbabilidad (improbability factor): Asumir que es improbable que un error conocido
cause verdaderos problemas.

Martillo de oro (golden hammer): Asumir que nuestra solución favorita es universalmente aplicable,
haciendo bueno el refrán a un martillo, todo son clavos.

Optimización prematura (premature optimization): Realizar optimizaciones sin disponer de la


información suficiente para hacerlo con garantías, sacrificando decisiones de diseño.

Programación de copiar y pegar (copy and paste programming): Programar copiando y modificando
código existente en lugar de crear soluciones genéricas.
Programación por permutación (programming by permutation): Tratar de aproximarse a una
solución modificando el código una y otra vez para ver si acaba por funcionar.

Reinventar la rueda (reinventing the wheel): Enfrentarse a las situaciones buscando soluciones
desde cero, sin tener en cuenta otras que puedan existir ya para afrontar los mismos problemas.

Reinventar la rueda cuadrada (reinventing the square wheel): Crear una solución pobre cuando ya
existe una buena.

6. Antipatrones de gestión de la configuración

Conflicto de extensiones (extension conflict): Problemas con diferentes extensiones que tratan de
gestionar las mismas partes del sistema (específico de Mac OS).

Infierno de dependencias (dependency hell): Escenario de problemas producidos por las versiones
de otros productos que se necesitan para hacer funcionar un tercero.

Infierno DLL (DLL hell): Problemas con las versiones, disponibilidad o proliferación de
DLLs (específico de Microsoft Windows)

Infierno JAR (JAR hell): Problemas con diferentes versiones o ubicaciones de ficheros JAR
(Java), típicamente causados por la falta de comprensión del modelo de carga de clases.