domingo, 15 de junio de 2008

Antipatrones

Esto esta demasiado gracioso, me es inevitable no publicarlo. Disfrutenlo.

Antipatrón de DiseñoDe Wikipedia, la enciclopedia libre

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 del 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

Antipatrones de gestión
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.

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.

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.
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.

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 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.

Antipatrones de programación
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): Entregar un componente de software antes de estar completo o completamente probado, de manera que la situación derive en el mantenimiento de sus características, buenas o malas (que tienden a quedarse fijas, como un río de lava que se seca por fuera).
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.
Secuencias mágicas (magic strings): Incluir cadenas de caracteres determinadas en el código fuente para hacer comparaciones, como tipos de eventos, etc.

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 las pruebas (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.

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, típicamente causados por la falta de comprensión del modelo de carga de clases.

Algunos antipatrones organizacionales
Avance del alcance (scope creep): Permitir que el alcance de un proyecto crezca sin el control adecuado.
Bloqueo del vendedor (vendor lock-in): Construir un sistema que dependa en exceso de un componente proporcionado por un tercero.
Diseño de comité (design by committee): Contar con muchas opiniones sobre un diseño, pero adolecer de falta de una visión unificada.
Escalada del compromiso (escalation of commitment): No ser capaz de revocar una decisión a la vista de que no ha sido acertada.
Funcionalitis acechante (creeping featuritis): Añadir nuevas funcionalidades al sistema en detrimento de su calidad.
Gestión basada en números (management by numbers): Prestar demasiada atención a criterios de gestión cuantitativos, cuando no son esenciales o difíciles de cumplir.
Gestión champiñón (mushroom management): Tratar a los empleados sin miramientos, sin informarles de las decisiones que les afectan (manteniéndolos cubiertos y en la oscuridad, como los champiñones).
Gestión por que lo digo yo (management by perkele): Aplicar una gestión autoritaria con tolerancia nula ante las disensiones.
Migración de coste (cost migration): Trasladar los gastos de un proyecto a un departamento o socio de negocio vulnerable.
Obsolescencia continua (continuous obsolescence): Destinar desproporcionados esfuerzos a adaptar un sistema a nuevos entornos.
Organización de cuerda de violín (violin string organization): Mantener una organización afinada y en buen estado, pero sin ninguna flexibilidad.
Parálisis del análisis (analysis paralysis): Dedicar esfuerzos desproporcionados a la fase de análisis de un proyecto, eternizando el proceso de diseño iterando sobre la búsqueda de mejores soluciones o variantes.
Peligro moral (moral hazard): Aislar a quien ha tomado una decisión a raíz de las consecuencias de la misma.
Sistema de cañerías (stovepipe): Tener una organización estructurada de manera que favorece el flujo de información vertical, pero inhibe la comunicación horizontal.
Te lo dije (I told you so): Permitir que la atención se centre en que la desoída advertencia de un experto se ha demostrado justificada.
Vaca del dinero (cash cow): Pecar de autocomplacencia frente a nuevos productos por disponer de un producto legacy muy lucrativo.

Relación alfabética de otros antipatrones
Arrojar al otro lado del muro (thrown over the wall).
Billete lobo (wolf ticket): Declarar compatibilidad con un estandar cuando esta no existe.
Blowhard Jamboree.
Cadena sin longitud (string without length).
Cajas de diálogos en cascada (cascading dialog boxes).
Callejón sin salida (dead end): Encontrar un problema que impide continuar trabajando, pero la dirección no permite corregir el problema. El equipo queda estancado.
Caminar por un campo de minas (walking through a mine field): Trabajar con un componente pobremente probado (usualmente inestable), y por tanto poco confiable.
Chivo expiatorio (scape goat).
Codificación brutal: Presionar a los programadores a trabajar sobre una arquitectura sin diseñar y sin requisitos evidentes.
Comité designado (appointed team): Crear un comité o grupo de trabajo para resolver un problema y no ocuparse de lograr que el grupo funcione.
Compensación equitativa (egalitarian compensation): Compensar al personal por el trabajo individual hecho.
Contenedor mágico (magic container).
Cuerpos tibios (warm bodies).
Culto al carguero (cargo cult).
Cultura del miedo (fear culture)): Ambiente en el que cada empleado tiene miedo de mostrar el resultado de su trabajo por miedo a ser despedido por tener errores.
Cultura del héroe (hero culture).
Decisión aritmética (decision by arithmetic).
Desarrollo distribuido geográficamente (geographically distributed development).
Desarrollo marcado por las herramientas (autogenerated stovepipe): Preferir una solución generada automáticamente sobre la mejor solución.
Descomposición funcional (functional decomposition): Traducir un programa de un lenguaje estructurado a uno OO usando una sola clase y muchos métodos privados.
Diseñar por diseñar (design for the sake of design): Realizar un diseño excesivamente complejo sin necesidad real.
Diseño con arquitectura impuesta (architecture as requirement): Imponer que el diseño considere, obligatoriamente, el uso de herramientas o métodos no necesariamente idóneos.
Diseño de fregadero (kitchen sink design).
Diseñadores empíricos (architects don't code): Incapacidad del grupo de diseño para evaluar la complejidad del objeto diseñado.
El correo electrónico es peligroso (email is dangerous): Peligro de olvidar que detrás de los emails recibidos hay personas de carne y hueso.
El gestor controla el proceso (manager controls process).
El traje nuevo del emperador (emperor's new clothes): Temor a señalar los defectos de un producto o proceso que un gerente o manager cree que funciona bien.
El viejo gran duque de York (the grand old Duke of York).
Ellos me entendieron (they understood me): Explicar a programadores o diseñadores junior lo que se espera de ellos muy brevemente, y asumir que entendieron lo que se les pidió.
Embudo de excepciones (exception funnel): Atrapar una excepción e ignorarla, sin reportarlo.
Entrenar al entrenador (train the trainer).
Es un problema de operadores (it is an operator problem).
Esconder las armas (cover your assets).
Falsa economía (false economy): Permitir que los recortes de presupuesto afecten la eficiencia de los trabajadores (las pérdidas terminan siendo mayores que lo ahorrado).
Falso punto final subrogado (false surrogate endpoint).
Fechas en punto flotante (floating point times).
Haz tu propia base de datos (roll your own database).
Ingenieros compatibles e intercambiables (plug compatible interchangeable engineers).
Introducción de dificultad por analogía (analogy breakdown): Diseñar por analogía con problemas resueltos, posiblemente introduciendo dificultades no inherentes al problema, o descuidando dificultades propias del nuevo caso que se maneja.
Invocar a constructores con nulos (passing nulls to constructors).
La disputa familiar (the feud).
La experiencia mata el diseño (architecture by implication): Descuidar el diseño por confiar excesivamente en la experiencia previa.
Los clientes son tontos (customers are idiots): Pensar que uno sabe más que el cliente, y por tanto no es necesaria una investigación con el cliente.
Maníaco del control (control freak).
Máquina de Rube Goldberg (Rube Goldberg machine): Realizar implementaciones muy complejas para tareas sencillas.
Matar al mensajero (shoot the messenger).
Matar dos pájaros de un tiro (kill two birds with one stone).
Matrimonio sumarísimo (sumo marriage).
Mazorca de maíz (corn cob).
Mecanismos de recompensa discordantes (discordant reward mechanisms).
Mezclador de software (software merger).
Miedo al éxito (fear of success): Permitir que las únicas razones de que los trabajos no se completen sean de índole social.
Moneda en punto flotante (floating point currency): Utilizar una representación en punto flotante para valores que representan dinero, lo que puede provocar pérdida de precisión.
Morir planificando (death by planning).
Nacionalismo (national ism).
Navaja suiza (swiss army knife): Intentar crear un producto que solucione varios problemas poco relacionados entre sí.
No especificar (specify nothing).
No inventado aquí (not invented here).
Otra reunión más lo resolverá (yet another meeting will solve it).
Otro programador más (yet another programmer).
Presunto heredero (heir apparent).
Proceso a prueba de idiotas (idiot proof process).
Programador discordante (net negative producing programmer).
Proyecto del día de la marmota (ground hog day project): Discutir los mismos temas en todas las reuniones, sólo para llegar a la conclusión de que "algo debe hacerse".
Prueba incompleta (asynchronous unit testing): Descuidar en la etapa de pruebas, algunas unidades en todos los casos, o todas las unidades en algunos casos.
Quiero estimaciones ahora (give me estimates now): Dar estimaciones sin tener suficientes datos para hacerlas.
Requisitos esparcidos por la pared (requirements tossed over the wall).
Requisitos ocultos (Hidden requirements).
Si funciona, no lo toques (if it is working don't change).
Somos tontos (we are idiots): Pensar que el conocimiento interno del problema es peligroso (por riesgo de que sea pobre o equivocado), y pedir validación del cliente para cada característica o decisión mayor.
Tarjetas CRCI (CRCI cards).
Tormenta de reproches (blame storming).
Torre de vudú (tower of voodoo).
Trampa para osos (bear trap): Invertir mucho en una herramienta poco adaptada o factible, de manera que después es imposible deshacerse de ella.
Único punto de salida de función (single function exit point).
Valor por defecto indefinido (zero means null): Escoger un valor arbitrario para representar la indefinición, sin garantizar que ese valor no puede realmente ocurrir.
Violencia intelectual (intellectual violence).

Enlaces externos
C2.com (antipatrones) Portland Pattern Repository's Wiki

No hay comentarios: