Antipatrones: aprendiendo de los errores de otros (II) #bdc11

Hace unas semanas os traje la primera parte de la charla sobre antipatrones que di en la Barcelona Developers Conference, en la que definimos los antipatrones como una solución a un problema que genera consecuencias negativas. Además, vimos que se pueden agrupar en antipatrones:

  • De desarrollo
  • De arquitectura (o de diseño)
  • De gestión

En esta segunda parte hablaremos sobre los antipatrones de arquitectura de software.

La definición de la  arquitectura de una aplicación es posiblemente la más difícil de todas las decisiones que se tienen que tomar en un proyecto, ya que afectará en gran medida al éxito o fracaso de la aplicación. Una arquitectura que no abarque toda la problemática de una solución de software es tan peligrosa como otra que sea muy compleja y difícil de desarrollar.

Muchas veces las decisiones de diseño se toman sin conocer partes de la solución que se quiere desarrollar y con muy poco tiempo; pero eso ya lo veremos en el próximo capítulo de esta serie, cuando hablemos de los antipatrones de gestión de proyectos, de momento vamos a centrarnos en algunos de los antipatrones más conocidos de diseño o arquitectura (no son los únicos, tenéis una lista aquí).

 

Big Ball of Mud (Gran bola de lodo)

Big ball of mud

Describe un sistema que no tiene una estructura bien definida. Las responsabilidades y la información se encuentran esparcidas por los elementos, a veces están compartidas y otras repetidas. Además, es común que existan clases que nadie sabe qué hacen, pero que se mantienen en el código "por si acaso".

Este tipo de no-arquitectura es muy común en proyectos que llevan muchos años de desarrollo, en los que han intervenido gran número de personas y que nunca han tenido un responsable que indique el camino a seguir.

Rodrigo Corral suele referirse a este antipatrón como "Gran Bola de mierda", y afirma, muy acertadamente que sobre una bola de mierda no se puede añadir nada. Como mucho, podrás hacer otra pequeña bola de mierda al lado de la antigua y rezar para que funcione.

 

Yet another (useless) layer (¡Y otra capa más!)

Consiste en agregar otra capa más a una librería o framework con la excusa de intentar reducir el acoplamiento, pero normalmente las capas que se añaden son innecesarias ya que lo único que hacer es servir de envoltorio: tienen llamadas a métodos de objetos que están en otras capas. También es conocida como código lasaña o musaka (dependiendo de si lleva pasta o berenjenas :P).

Este antipatrón suele estar asociado a la moda arquitectónica del momento. Por ejemplo, desde la publicación del libro Guía de Arquitectura N-Capas DDD .NET 4 por parte de Microsoft se ha iniciado una polémica entre los que pretenden seguir la arquitectura planteada en el libro a rajatabla y los que saben que es únicamente una referencia para aplicaciones complejas (que curiosamente es lo que pone en la introducción del propio libro).

 

Reinventing the Wheel (Reinventar la rueda)

Reinventing_the_wheel

Consiste en intentar solucionar un problema conocido con una solución "ad hoc", inventada y desarrollada por nosotros y sin tener en cuenta los patrones de diseño, arquitectónicos ni de ningún tipo. La causa principal suele ser el desconocimiento y la soberbia. No es extraño encontrar un proyecto con su propia solución de loggin, su propio ORM o su propio serializador de JSON.

El principal problema de reinventar la rueda es que se rompe con los estándares y es muy difícil de mantener, ya que se cumple con la regla de "si es para mí, no hace falta que lo documente". Además, como es una solución para salir del paso, tampoco tendrá tests unitarios, con lo que el conocimiento sobre qué hace y cómo lo hace se suele ir con la persona que lo implementó.

 

 

Golden Hammer (Martillo de oro)

Golden_Hammer

El nombre de este anitpatrón viene de la frase: "Si todo lo que tienes es un martillo, todos tus problemas se convertirán en clavos". Se trata de intentar utilizar nuestra solución favorita para TODOS los problemas. Se puede aplicar como antipatrón de desarrollo como de diseño.

Un ejemplo muy gráfico sería el de intentar aplicar una arquitectura CQRS para hacer un blog. En este caso, se trata claramente de una arquitectura innecesariamente compleja para lo que queremos hacer.

Este antipatrón suele producirse cuando se quieren anticipar requerimientos futuros, ya que el cliente de momento no los tiene decididos o no ha pensado en ellos.

 

 

¿Qué consecuencias tienen?

Durante un tiempo una arquitectura deficiente no tiene más consecuencias que hacer la aplicación poco mantenible, pero, ¿qué pasa cuando empiece a tener problemas?

  1. El equipo está acostumbrado a trabajar mal, no sigue buenas prácticas ni mejoran el código existente.
  2. La aplicación tiene un índice de mantenibilidad que tiende a infinito, cualquier cambio es difícil y suele llevar asociado la generación de nuevos bugs.
  3. Los clientes ven que la aplicación no funciona como ellos quieren, además, hay nuevos bugs y se tarda mucho en solucionarlos. La relación con el cliente se enturbia.
  4. Volvemos al punto 1, pero con más presión.

Jurgen Appelo lo explica perfectamente en esta presentación: Complexity Thinking.

 

¿Cómo se solucionan?

Lo que tienen en común estos 4 antipatrones es que nos encontramos en un proyecto que tiene una arquitectura o un diseño que no le corresponde. Hay que tratar cada situación de una manera individualizada y podemos afrontar los cambios de dos formas: hacerlo todo de nuevo o refactorizar lo que hay.

La opción de hacerlo todo de nuevo es fácil, pero tiene el problema de que no se verán resultados hasta que el proyecto esté avanzado. Y mientras avancemos habrá que seguir dándole soporte a la aplicación tal y como está. Además, como la nueva versión no funcione, como mínimo, 10 veces mejor que la actual, seremos el hazmerreír de la empresa.

Refactorizar sobre lo que hay es mucho más complicado que hacerlo todo de nuevo, pero tiene la ventaja que se puede hacer de manera progresiva, planteando plazos en los que se implantarán las mejoras y aprendiendo de nuestros errores. Scrum puede ser una buena ayuda para esto. Lo importante es no intentar abarcar todos los cambios a la vez, sino de manera gradual y planeada: primero plantear una arquitectura, después cambiar el acceso a datos, lo siguiente agrupar la lógica de negocio, ... refactorizar tanto a nivel de código como de estructura.

Pero afrontar estos cambios conlleva dos problemas añadidos: la presión y la resistencia al cambio. Tendremos una presión superior a seguir haciendo lo de siempre, ya que tendremos que sacar mejores resultados en menos tiempo. Además, tendremos que enfrentarnos a la resistencia al cambio dentro del propio equipo y de la organización. No es fácil hacer que una organización trabaje de una forma diferente a la que está acostumbra, pero sobre eso hablaremos más adelante, cuando tratemos los antipatrones de gestión de proyectos.

Agregar un comentario

You must Iniciar sesión to comment.