Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
Mostrando entradas con la etiqueta antipatrones. Mostrar todas las entradas
Mostrando entradas con la etiqueta antipatrones. Mostrar todas las entradas
martes, 9 de abril de 2019
Manos sobre teclado Hace unas semanas leía el post C# Async Antipatterns de Mark Heath, y encontré en él problemas en la implementación de código asíncrono que, coincidiendo con el autor, creo que son bastante frecuentes.

Como la asincronía ha llegado para quedarse y aún hay desarrolladores que no lo tienen claro del todo, he pensado que sería interesante traducir y republicar aquí el post, por supuesto, con permiso expreso de su autor (thank you, Mark! ;))

¡Vamos allá!
miércoles, 9 de marzo de 2011
Hace muchos, pero muchos, años ya comenté por aquí un buen ejemplo de lo que ocurre cuando un desarrollador diseña el interfaz de usuario de una aplicación. También, ya más recientemente, profundizaba en este curioso tema en el post titulado Indicios de que tu interfaz de usuario fue creado por un programador.

Esta semana he vuelto a encontrar un ejemplo, creo que bastante ilustrativo, del fenómeno. La captura de pantalla pertenece a la herramienta gratuita Bulk Rename Utility, una utilidad imprescindible cuando necesitamos renombrar de forma masiva archivos en un directorio.

Bulk rename utility
Funcionalmente, ninguna pega, más bien todo lo contrario: es potentísima, e incluso una vez la has utilizado un poco resulta hasta fácil de manejar.

Ahora bien, a nivel de interfaz la primera impresión es una auténtica agresión al usuario. De hecho, hasta los propios autores se lo toman con filosofía, como podemos leer en el primer párrafo del tutorial de su web:
“You've installed the software, you've launched it, and you now see a million and one controls and boxes on the screen. The first thing to do is DO NOT PANIC!”
Pero vaya, como ya decía años atrás, el que esté libre de pecado que tire la primera piedra ;-)

Publicado en: Variable not found.
lunes, 17 de mayo de 2010
Desarrolladores tatuados ¡Ah, cómo nos parecemos los desarrolladores! Independientemente de la tecnología, el tipo de aplicación, o el cliente, parece que llevamos tatuados de serie unos comportamientos que repetimos una y otra vez ante escenarios similares.

Debe ser por eso que me divierten y me identifico tanto con los posts que enumeran estos hábitos tan comunes, como el clásico las “20 respuestas más utilizadas por los desarrolladores cuando sus programas no funcionan”, que pulula por la red desde hace muchos años y del que he encontrado versiones en todos los idiomas, por lo que soy absolutamente incapaz de citar la fuente exacta.

El hecho es que justo en el momento en que se nos informa de que algo ha fallado en una de nuestras aplicaciones, el cerebro comienza a trabajar aceleradamente en busca de una excusa explicación, por lo que he pensado que combinando esta lista de frases con unos sabios consejos, seguro que puedo ayudar a más de uno a evitar las tensiones derivadas de los errores en programación.

Y es que, al final, seguro que todos acabamos diciendo aproximadamente lo mismo…

20. “¡Qué raro!”. Primera regla del desarrollador experimentado: mostrar asombro cuando algo falla. Alguien que no se extrañe de la aparición de un error puede aparentar ser bastante mediocre. Hay quien incluso, para acentuar más aún su profesionalidad, añade “¡Imposible!”.

19. “Nunca había pasado antes”. Por si no queda claro con el conjunto de exclamaciones anteriores, apostillar con esta declaración deja claro que os encontráis ante algo insólito. Esto, además, puede ser útil para despertar el espíritu aventurero en tu interlocutor, y hacerlo partícipe en el enfrentamiento a lo desconocido que estáis a punto de comenzar.

18. “Ayer funcionaba”. Busca un soporte sólido para aferrarte, una referencia fiable como esa. Decir que ayer funcionaba es una afirmación ideal: difícil de probar, y si estás ante alguien cándido e inocente, será suficiente para convencerlo de que el error se ha generado hoy mismo, como por arte de magia.

17. “¿Cómo es posible?”. Otra oportunidad para demostrar tu asombro, que además surte mayor efecto si lo sigues con una explicación que tu interlocutor no sea capaz de entender: “cuando I,J,K y no M,N,L es imposible que X,Y,Z”.

16. “Debe ser un problema hardware”. Segunda regla del desarrollador experimentado: si la cosa se complica, puedes ir abriendo el camino a nuevas posibilidades, alejadas de nuestra responsabilidad. Nada podemos hacer contra fallos en la máquina, nosotros sólo entendemos de software. De hecho, si somos incapaces de dar con el problema (y por tanto incapaces de solucionarlo), echar las culpas al metal es una vía de salida de lo más airosa.

¡Te vas a tragar la pantalla! 15. “¿Qué hiciste mal para que fallara?”. Duda siempre de la lucidez del usuario. Si lo acusas de ser un zoquete tendrá que dedicar su tiempo de proceso a defender su postura, y no a vapulearte como te mereces.

14. “Hay algo raro en tus datos”. Es una variación más ligera del caso anterior; estás descargando responsabilidad sobre el usuario, aunque de forma menos agresiva, pues no es un ataque directo a su persona, sino a los datos que utiliza. Esta fórmula puede ser útil y prudente si, por ejemplo, el usuario del sistema es tu jefe.

13. “¡No he tocado ese módulo en semanas!”. Eso es, deja claro que tú no has tocado nada, y que por tanto la responsabilidad no es tuya. Si el módulo funcionaba hace un mes y no has tocado nada, está claro que la culpa el del usuario, del entorno, o del propio desgaste, como las ruedas de un coche.

12. “Debes estar utilizando una versión incorrecta”. Esta es una técnica avanzada para aplicar una vez te has percatado, en silencio claro está, de que había un error tuyo en tu aplicación. Acusa al usuario de utilizar una versión antigua del software, y suminístrale la versión correcta, en la que obviamente ya has parcheado el error.

11. “Se trata sólo de una casualidad”. Utiliza el azar como causa de los problemas; es impredecible, incontrolable y misterioso, una cortina de humo ideal para esconder nuestras meteduras de pata.

10. “Uno no puede probarlo todo”. No somos Dioses… quizás estemos muy cerca, pero no lo somos. Esta frase, a utilizar sólo en casos señalados, puede mostrar humildad y apelar a la bondad del interlocutor para disminuir la tensión. O también, puede servir para arremeter contra tu organización, la falta de recursos, de tiempo, etc., que el usuario empatizará y lamentará contigo.

9. “Eso no puede ser la causa del problema”. Sé tajante; aunque tenga razón, no permitas que un usuario listillo te revele el motivo exacto por el que ha fallado tu aplicación, pues nadie la conoce mejor que tú. Si después de usar esta frase confirmas que la causa era la apuntada por este individuo, no lo reconozcas, y utiliza verborrea técnica para desviar la atención a otras causas.

8. “Eso funciona, aunque no lo he probado”. Un desarrollador profesional no necesita probar las cosas para saber que funcionan, eso es cosa de débiles e inseguros. Una afirmación tan rotunda desequilibrará al interlocutor y lo hará dudar de su criterio a la hora de detectar el error, momento que puedes aprovechar para rematar con cualquier otra frase.

7. “Alguien debe haber cambiado mi código”. Otra regla de oro del desarrollador, aunque compartida con otras profesiones: échale las culpas a otro. Una vez demostrado que hay un fallo y que no puedes hacer responsable al usuario, no hay nada mejor que echar la culpa a los compañeros. Y si crees que no es ético, recuerda: ellos también lo harían.

6. “¿Has comprobado si tienes un virus?”. Los virus, esos seres misteriosos que sólo podemos comprender los iniciados y de los que todo el mundo ha oído historias terribles, son también firmes candidatos a salvarnos el trasero cuando la cosa se está poniendo peligrosa. Dado que la respuesta a esta pregunta casi siempre va a ser negativa, estamos ganando tiempo e introduciendo un factor externo sobre el que descargar las culpas, haciendo al usuario responsable por su incompetencia para mantener su equipo limpio.

BSOD 5. “Bueno, no funciona, pero mola, ¿eh?”. Ante una encerrona, apela al sentido del humor de tu interlocutor. Intenta detectar algún aspecto positivo del desastre, y preséntalo de forma atractiva para el usuario. ¿Un proceso tarda demasiado? Así tienes más tiempo para estirar los músculos; ¿La aplicación se cierra violentamente? Así puedes apagar antes el equipo e irte a casa; ¿Una BSOD? Fíjate qué fondo de pantalla azul eléctrico tan espectacular te pone el programa cuando falla.

4. “No puedes usar esa versión en tu sistema” Cuando el número de errores sea tan alto que pueda poner en peligro tu credibilidad como profesional, no reconozcas haberlos cometido; utiliza motivos estructurales como el hardware, los virus, o el versionado de sistemas para hacerles ver que eres totalmente inocente.

3. “¿Por qué quieres hacerlo así?” Una posibilidad muy socorrida es a veces instruir al usuario para que realice las tareas justo de la forma en que la aplicación funciona correctamente, censurándole rápida y tajantemente los intentos de salirse del camino marcado. A veces es más fácil adaptar el usuario a la aplicación que viceversa.

2. “¿Dónde estabas cuando el programa falló?” Ideal para aplicaciones que funcionan como procesos por lotes, o para intentar culpar al usuario de su ausencia en un momento vital como en el que se produjo el problema. Sobre todo si sabemos que el usuario es tendente a despistarse, esta puede ser un arma realmente interesante.

1. “No es un error, es que el programa funciona así”. Aprovecha la delgada línea que separa un bug de una feature. Esta técnica avanzada te permitirá desviar la atención hacia las personas que decidieron las funcionalidades, recogieron los requisitos, o validaron el software, pero nunca hacia el desarrollador que simplemente siguió las instrucciones.

¡En mi máquina funciona!Y por último, la frase más utilizada sin duda por los desarrolladores:

0. “¡En mi máquina funciona!” Desconcierta al interlocutor, y queda como debes, por encima de todos. El software funciona en entornos controlados como el tuyo, propios de un experto, donde todo está perfectamente en orden y lejos del alcance de las manazas del usuario final.

Eso sí, hay que estar preparados para una respuesta como la siguiente:
"¡No me importa si funciona en tu máquina!
¡No estamos vendiendo tu máquina!"
-- Vidiu Platon
Publicado en: Variable not found
lunes, 16 de noviembre de 2009

¡Programadiseñadores al poder! Ya sabemos lo que suele ocurrir cuando los programadores diseñamos interfaces de usuario ;-). Para seguir profundizando en este curioso e inevitable fenómeno, Ian Voyce ha publicado hace unas semanas el divertido post The 7 signs your UI was created by a programmer, en el que recoge pistas que nos ayudarán a determinar si el interfaz de la aplicación que usamos a diario está creado por un diseñador experto en usabilidad, o ha sido el propio desarrollador el encargado de dichas tareas.

Bueno, en realidad se trata más bien de una lista con malos hábitos en el diseño de interfaces, y no necesariamente creados por programadores, pero ciertamente me he reconocido en alguno de los puntos y me han hecho gracia. Los cito y comento a continuación:

  • Iconos de exclamación en cuadros de diálogo
    Efectivamente, cuando incluimos una exclamación en un cuadro de diálogo no pensamos en que es posible que el usuario vea el mensaje 50 veces al día, con lo que dejaría de ser ese mensaje asombroso y puntual que pensamos en un principio. Hoy en día, muchas aplicaciones utilizan un tono mucho más neutral y cercano para enviar mensajes al usuario.

  • Mensajes con dobles negaciones en cuadros de diálogo, del tipo “¿Seguro de que no quieres perder tus cambios?” -- Hmm… sí… digooo, no…  También son muy propias construcciones más complejas de la cuenta, paradójicas o inesperadas, como “Su mensaje no se ha enviado, ¿desea descartarlo?”, que ponen a prueba los reflejos de cualquier usuario.

  • Orden de tabulación inexistente, o incorrecto, que fuerzan a que la navegación se realice exclusivamente a golpe de ratón. Y especialmente en aplicaciones de entrada masiva de información, el cambio de teclado a ratón y viceversa es terrible. Y paraGroupboxes para todo.. porque mola hacernos conscientes de ello, nada como dar vacaciones un rato al animalito y ver lo bien que manejamos determinadas aplicaciones.

  • Groupboxes rodeándolo todo… porque hay sitios donde queda bonito, aunque no esté agrupando nada ;-). Me confieso: durante años, he rodeado de groupboxes todo lo que se me ponía por delante, porque me parecía más agradable a la vista. Ahora lo estoy dejando ;-)

  • IconoIconos creados en el IDE, je, este es otro de mis puntos fuertes: soy un fiera diseñando iconos desde el editor de Visual Studio. El problema es que, a pesar de lo orgulloso que estoy siempre de mis creaciones artísticas, no quedan bien e incluso introducen un cierto tufillo a cutre en las aplicaciones.

  • Utilización de grids, debido a lo que llama Voyce “la enfermedad de considerar que Excel es lo máximo en diseño de interfaces de usuario”, que fomenta la creación de rejillas con controles de lo más potentes y variopintos en las filas de datos (calendarios, gráficos, etc.).

  • Message Boxes no implementados, el equivalente en los interfaces de usuario a los TODO en el código fuente :-DD. Buena analogía. Algo parecidos serían los mensajes del tipo “Este mensaje no debería aparecer nunca” que alguna vez he encontrado por ahí, auténticos actos de rebeldía contra sus respectivos creadores.

  • Uso excesivo de cuadros de diálogo, incluso en situaciones en las que perfectamente podríamos obviarlos por no ofrecer información útil para el usuario, que no va a poder entender, o donde no se requieren decisiones por su parte.

    Los componentes necesarios han sido detectados. Accediendo...Esto es algo muy frecuente de ver. Por ejemplo, el otro día accediendo a una aplicación web para la que es necesario contar con certificado digital, me saltó la alerta que muestro a la derecha:

    Sí, probablemente los componentes Java necesarios para la autenticación y firma electrónica hayan sido detectados con éxito, pero… ¿realmente era necesario interrumpir mi navegación para informarme de ello? ¿Un usuario, sabrá interpretar el mensaje? Y en cualquier caso, ¿le aporta algo? No sé, no sé… me da que es un alert() creado por un desarrollador durante las pruebas y que al final se quedó ahí para la posteridad.

Hasta aquí las citadas en el post original, aunque siguiendo en la misma línea, puedo añadir algunas más de propia cosecha:

  • Cuadros de diálogo con mensajes y botones inconsistentes. Mensajes del tipo “¿desea cancelar la operación?” en cuyo pie aparece un botón “Aceptar” y otro “Cancelar” siempre me dejan pensando un rato. Si pulso aceptar, ¿estoy aceptando la cancelación, o justo lo contrario?… Muchas veces, parece que sólo podemos confiar en el azar.

  • Cuadros de mensaje con demasiados (o demasiados pocos) botones. No siempre atendemos a la Ley de Hick, que nos dice que “el tiempo que se tarda en tomar una decisión aumenta a medida que se incrementa el número de alternativas”, y eso nos lleva a crear cuadros de diálogo con muchos, demasiados, botones que el usuario debe estudiar.

    Y justo en el lado contrario, pero igualmente desconcertantes, son los cuadros de diálogo de introducción de datos sin ningún botón de aceptación, en los que su cierre (con la X de la esquina superior) implica el salvado de datos.

  • Interfaz descuidado. Y no hablo de bonito o feo, términos bastante subjetivos, sino de descuidado: controles sin alinear, con tamaños no proporcionales al contenido pretendido, sensación de desorden, faltas de ortografía… Esto no es un problema de interfaces creados por desarrolladores, sino creados por gente que no pone el más mínimo cariño en lo que hace, independientemente de su puesto de trabajo.

  • Interfaces monocromos, mi especialidad. Como inútil reconocido en temas de diseño, me considero absolutamente incapaz de crear algo medio aparente con más de un color (eso sí, empleando distintas tonalidades ;-)). Nunca he entendido la compleja lógica que hay detrás del “eso no pega con aquello”, que algunos/as parecen dominar de serie.

  • Controles con trastorno de personalidad. Un clásico es encontrar un grupo de checkboxes actuando como un grupo de radios. A ver, si sólo vamos a poder elegir una de las opciones, ¿por qué no usamos directamente el control específicamente ideado para ello? ¿Y un desplegable con las opciones "Activar" y "Desactivar"? ¿No sería más claro poner un checkbox?

Artículo original: The 7 signs your UI was created by a programmer

Publicado en: Variable not found.

domingo, 3 de mayo de 2009

Existen numerosas aplicaciones que permiten analizar nuestros desarrollos con el objetivo final de incrementar la calidad de los mismos. FxCop, por ejemplo, es capaz de analizar los ensamblados y avisarnos cuando se encuentra con incumplimientos de las pautas de diseño para desarrolladores de librerías para .Net Framework (Design Guidelines for Class Library Developers). También hace tiempo comenté por aquí la disponibilidad de  Microsoft Source Analysis for C#, una herramienta que se centra en el código fuente y el cumplimiento de reglas de codificación.

Ahora, gracias al ofrecimiento de Patrick Smacchia, lead developer del producto, he podido probar NDepend, una herramienta de análisis de código de la que había oído hablar y que va mucho más allá que las citadas anteriormente.

La principal misión de NDepend es ayudarnos a incrementar la calidad de nuestros sistemas desarrollados con .NET mediante el análisis de sus ensamblados y código fuente desde distintas perspectivas, como la complejidad de sus módulos, el tamaño de los mismos, las interdependencias entre ellos, etc. Es decir, a diferencia de otros analizadores, su objetivo no es avisarnos de aspectos como la utilización de convenciones de codificación (aunque también puede hacerlo), o el uso de buenas prácticas de diseño, sino ayudarnos a determinar, por ejemplo, cuándo ponemos en peligro la mantenibilidad y evolución de un sistema debido a la complejidad  o al fuerte acoplamiento de algunos de sus componentes, por citar sólo algunos criterios.

El entorno gráfico

VisualNDepend es el entorno gráfico de la herramienta, y nos ofrece un entorno de trabajo muy potente e intuitivo, aunque durante los primeros minutos pueda resultar algo complejo debido a la cantidad de información mostrada.

Iniciar el análisis de un sistema es muy sencillo; una vez seleccionado el ensamblado, conjunto de ensamblados o proyecto a estudiar, el sistema realiza el análisis, del cual se obtiene un informe bastante completo, basado en web, sobre el mismo (podéis ver un ejemplo de informe en la página del producto). En él se recogen:

  • métricas de la aplicación, entre las que encontramos el número de líneas de código, comentarios, número de clases, métodos, etc., así como datos estadísticos relativos a la complejidad, extensión y estructura del código.
  • métricas por ensamblado, donde se refleja, por cada uno de los ensamblados que componen la solución, datos sobre su tamaño, grados de cohesión, acoplamiento, y otros aspectos relativos a su complejidad e interdependencia.
  • Vista de estructura vista de estructura (captura de la derecha) que muestra la distribución de componentes, la granularidad y su complejidad relativa según el tamaño de los bloques visualizados.
  • diagrama de abstracción e inestabilidad, que posiciona cada ensamblado en función del número de clases abstractas e interfaces que presenta y su dependencia del resto de elementos.
  • relación entre ensamblados, que detalla las interdependencias entre ensamblados del proyecto, los posibles ciclos, así como un posible orden de generación.
  • consultas y restricciones CQL, que realiza una serie de consultas predefinidas sobre los ensamblados y el código que nos ayuda a detectar una infinidad de problemas en nuestros desarrollos, desde aspectos relativamente simples como el exceso de métodos en clases o el incumplimiento de ciertas convenciones de nombrado, hasta problemas en la cobertura de los tests generados con NCover o Visual Studio Team System.

Pero lo mejor del entorno gráfico no es poder generar un análisis en formato web para poder consultarlo más adelante, de hecho esto puede conseguir también con la aplicación de consola que incluye NDepend. Lo mejor son las fantásticas herramientas interactivas que nos permiten navegar a través de nuestras aplicaciones, cambiar de vista, ampliar información sobre cualquier elemento, y realizar consultas en tiempo real, siempre ofreciendo unos resultados muy claros y visuales, como:

Diagrama de dependencias

  • diagrama de dependencias entre todo tipo de elementos, como clases, espacios de nombres, o ensamblados. Resulta muy útil, además, configurar el tamaño de los bloques, el grosor del borde y el de las flechas de unión para que sean proporcionales a la complejidad, tamaño y una larga lista de criterios.
  • Tabla de dependencias matriz de dependencias, que muestra de forma visual las relaciones de utilización entre espacios de nombres, tipos, métodos o propiedades, con posibilidad de ir ampliando información.
  • comparación entre ensamblados, mostrándonos los cambios producidos entre, por ejemplo, dos versiones de una misma librería o aplicación.
  • navegación avanzada por el código a través del uso del menú contextual que facilita la rápida localización de referencias, directas e indirectas, hacia y desde un método, propiedad o tipo existente.
  • enlace con Reflector, una herramienta indispensable, con la que se integra perfectamente gracias a su plugin.

 

CQL (Code Query Language)

Sin duda, una de las características más interesante que tiene NDepend es el soporte del lenguaje de consulta CQL (Code Query Language), que nos ofrece la posibilidad de tratar nuestro código y ensamblados como si fuesen una gigantesca base de datos sobre la que podemos realizar consultas de forma muy natural.  Las posibilidades que esto ofrece son tan amplias que prácticamente todas las funcionalidades de la aplicación están basadas en órdenes CQL prediseñadas que acompañan al producto, aunque podemos crear todas las consultas personalizadas que necesitemos, como por ejemplo:

/* Obtiene los métodos que escriben una propiedad */
SELECT METHODS WHERE IsDirectlyWritingField "Model.Cliente.Nombre"

/* Obtiene métodos que acceden incorrectamente a los
datos desde la capa de interfaz
*/
SELECT METHODS FROM NAMESPACES "Interfaz" WHERE IsDirectlyUsing "MySql.Data"

/* Obtiene los 10 métodos con más líneas de código */
SELECT TOP 10 METHODS ORDER BY NbLinesOfCode DESC

/* Obtiene los métodos considerados "peligrosos" según su complejidad ciclomática */
SELECT METHODS WHERE CyclomaticComplexity > 20


Editor de CQL con intellisenseAdemás de consultas CQL cuyo resultado podremos observar de forma directa tanto visualmente como en forma de listado, es posible incluir restricciones (WARN) que hará que el sistema nos alerte durante el análisis de un proyecto que cumpla las condiciones especificadas. Por ejemplo, la siguiente restricción nos avisará cuando exista un cierto tufillo a complejidad excesiva en un método (que haya sido definido con más de 10 parámetros):

WARN IF Count > 0 IN  SELECT METHODS WHERE NbParameters > 10

Estas consultas pueden ser añadidas (en la versión Pro) e integradas en los análisis, así como modificar las existentes, de forma que el producto puede ser personalizado a nuestras convenciones o necesidades específicas.

Otra posibilidad es incluir dentro del código de un ensamblado las restricciones que deseamos que se cumplan, expresándolas en lenguaje CQL embebido en un atributo de tipo CQLConstraint aplicado a sus elementos:

Afortunadamente existe mucha información disponible en la web sobre el lenguaje CQL, y consultas que nos muestran cómo sacarle el máximo partido.

Instalación e integraciones

NDepend se distribuye en formato .zip, y que puede ejecutarse directamente una vez descomprimido el contenido sobre una carpeta. La licencia, una vez obtenida, es un archivo XML firmado digitalmente que debemos colocar en el directorio de la aplicación, y listo.

Integración con VS y Reflector

Ya en ejecución, desde el menú “options” es posible configurarlo para que se integre con Visual Studio 2005, 2008 y como he comentado anteriormente, con el magnífico Reflector, con el que hace una excelente pareja.

Asimismo, es posible utilizarlo en sistemas como MSBuild y NAnt, facilitando así su uso en entornos de integración continua y montaje automatizado, para los que ofrece librerías

Finalmente, he de aclarar que NDepend es una aplicación comercial, aunque dispone de una versión limitada gratuita utilizable por universidades, desarrolladores open source e incluso, durante un tiempo determinado, de prueba en proyectos comerciales.

En cualquier caso, no dudéis en probarlo: os dará un control sobre vuestro código difícil de conseguir con otras herramientas.


Publicado en: www.variablenotfound.com

miércoles, 27 de febrero de 2008
Bonito plato de spaghettiSabemos que los patrones son plantillas reutilizables que podemos usar para solucionar problemas habituales en el proceso de desarrollo de software. Así, permiten utilizar soluciones fiables y bien conocidas a problemas concretos, aprovechando experiencias previas como base para la consecución de mejores resultados en los nuevos desarrollos.

Pues bien, justo en el lado opuesto se encuentran los antipatrones, que definen situaciones y comportamientos que, según experiencias anteriores, nos conducen al fracaso en proyectos de desarrollo de software, es decir, son soluciones o planteamientos que se han demostrado incorrectos.

Y es ahí donde radica su interés: la observación y conocimiento de los mismos puede evitarnos resultados desastrosos, o actuar como alertas tempranas ante decisiones o dinámicas incorrectas, permitiéndonos prevenir, evitar o recuperarnos de estos problemas.

Al igual que en los patrones, su descripción está relativamente formalizada y suele recoger los siguientes aspectos:
  • nombre del antipatrón, así como su "alias"
  • su tipología: organizacional, de análisis, desarrollo... (veremos esto más tarde)
  • contexto y entorno en el que se aplica
  • descripción del problema concreto
  • síntomas, y consecuencias de la aplicación del antipatrón
  • causas típicas y raíces del problema
  • refactorización a aplicar, es decir, una descripción de cómo podríamos replantear el problema y conseguir una solución positiva.
  • ejemplos y escenarios para su comprensión.
  • soluciones relacionadas con la propuesta.

Por ejemplo, un resumen del clásico antipatrón que reconoceréis muy rápidamente, el llamado spaghetti code:

Nombre:Spaghetti Code
Tipología:Desarrollo
Problema:Existencia de una pieza de código compleja y sin apenas estructura que dificulta enormemente su mantenimiento posterior
Síntomas y consecuencias:
  • Tiempo de mantenimiento excesivo debido a la necesidad de estudio del código
  • Código no reutilizable
  • Aparición del temido "es mejor reescribirlo"
  • Métodos y funciones muy extensas
  • Abuso de variables globales
Causas:
  • Inexperiencia de desarrolladores
  • Reutilización de código de prototipos rápidos
  • Ausencia de diseño previo a la implementación
  • Desarrolladores trabajando en solitario
  • Falta de revisiones de código
Solución positiva:
  • Aplicar refactorización mientras se programa
  • Usar disciplinas de desarrollo específicas, métricas y buenas prácticas
  • Realizar y desarrollar el diseño del sistema antes de implementar

Según según la Wikipedia, los antipatrones se clasifican en los siguientes grupos, atendiendo a las áreas a las que afectan:
  • Antipatrones Organizacionales, que incluyen prácticas nocivas a este nivel, como pueden ser, entre otros:
    • Gestión de champiñones (Mushroom management), o mantener al equipo en la oscuridad, desinformado, y cubierto de porquería.
    • Parálisis en análisis (Analysis paralysis), o quedar inmovilizado debido a un análisis o precaución excesiva, en contraposición a la siguiente:
    • Extinción por intuición (Extint by instinct), llegar a la muerte por adelantarse demasiado y usar la intuición para la toma de decisiones.
  • Antipatrones de Gestión de proyectos, describiendo problemas en la gestión de proyectos, como los célebres:
    • Marcha de la muerte (Death march), que describe el avance de determinados proyectos hacia el fracaso aunque todo el personal, excepto los gerentes, saben que al final se darán el castañazo.
    • Humo y espejos (Smoke and mirrors), o la demostración de funcionalidades o características no implementadas como si fueran reales, lo que siempre he llamado "enseñar cartón piedra".
  • Antipatrones de Gestión de equipos, que recoge problemas relacionados con la relación con y de equipos de trabajo, como:
    • Doble diabólico (traducción libre del término Doppelganger), personas que dependiendo del día pueden ser magníficos colaboradores o auténticos demonios.
    • Gestor ausente (Absentee manager), describiendo situaciones en las que el director está invisible periodos prolongados
  • Antipatrones de Análisis, categoría que engloba antipatrones relacionados con la fase analítica de los proyectos software, entre otros:
    • Retroespecificación (Retro-specification), o lo que viene a ser la realización del análisis una vez implementada la solución.
    • Especificación de servilleta (Napkin specification), también muy socorrida, que consiste en pasar al equipo de desarrollo las especificaciones del producto a crear descritas con muy poco detalle o informalmente.
  • Antipatrones de Diseño, que incluye malas prácticas de diseño de software que dan lugar a aplicaciones y componentes estructuralmente incorrectos:
    • Gran bola de lodo (Big ball of mud), realización de aplicaciones sin estructura reconocible.
    • Factoría de gas (Gas factory), diseños innecesariamente complejos.
    • Botón mágico (Magic Pushbutton), o implementación de funcionalidades directamente en los manejadores de evento (p.e., click) del interfaz.
  • Antipatrones en Orientación a objetos, como una especialización del anterior, describe problemas frecuentes en los diseños creados bajo este paradigma, como:
    • Llamar al super (Call super), obligar a las subclases a llamar a la clase de la que heredan.
    • Singletonitis, abuso del patrón singleton.
    • Orgía de objetos (Object orgy), o encapsulación incorrecta en clases que permite el acceso incontrolado a sus métodos y propiedades internas.
    • Otra jodida capa más (YAFL, Yet another fucking layer), o la inclusión excesiva de capas en un sistema.
  • Antipatrones de Programación, con un gran número de errores frecuentes a evitar, como:
    • Spaghetti code, comentando anteriormente.
    • Ravioli code, que consiste en la existencia de un gran número de objetos desconectados o débilmente acoplados entre sí.
    • Ocultación de errores (Error hiding), o capturar errores antes de que lleguen usuario, mostrando mensajes incomprensibles o simplemente no mostrar nada.
    • Números mágicos (Magic numbers), incluir números inexplicables en el código.
  • Antipatrones Metodológicos, o formas de desarrollar que se han demostrado incorrectas a lo largo del tiempo, como pueden ser:
    • Programación copy & paste, también llamada herencia de editor, consiste en copiar, pegar y modificar, en contraposición a la estritura de software reutilizable.
    • Factor de improbabilidad (Improbability factor), asumir que un error conocido es improbable que ocurra.
    • Optimización prematura (Premature optimization), según algunos la raíz de todos los males, consiste en sacrificar el buen diseño y mantebilidad de un software en benecificio de la eficiencia.
    • Programación por permutación (Programming by permutation), o intentar dar con una solución modificando sucesivamente el código para ver si funciona.
  • Antipatrones de Gestión de configuración, hace referencia a antipatrones relacionados con la gestión de los entornos de desarrollo y explotación del software, como las variantes del infierno de las dependencias (Dependency hell), o problemas de versionado de librerías y componentes:
    • DLL's Hell, el conocido y traumático mundo de las librerías dinámicas en Windows.
    • JAR's Hell, idem, pero relativo a las librerías Java.

Por no hacer el post eterno sólo he recogido unos cuantos, aunque existen cientos de ellos, y con una gran variedad temática: antipatrones para el desarrollo guiado por pruebas (TDD), antipatrones de manejo de excepciones, para el uso de arquitecturas orientadas al servicio (SOA), de rendimiento, de seguridad, centrados en tecnologías (p.e., J2EE antipatterns) o según el tipo de software (sistemas de gestión, tiempo real, videojuegos, etc.).

Y como conclusión personal, decir que me he visto reconocido en multitud de ellos, lo cual significa que muy descaminados no andan. Es más, si hiciera una lista con patrones y otra con los antipatrones que utilizo o he utilizado, la segunda tendría más elementos que la primera... ¿quizás es momento de reflexionar un poco?

Publicado en: http://www.variablenotfound.com/.