Una aplicación de Software se construye para satisfacer las necesidades de un cliente. Es por ello, que para definirla correctamente, es necesario entender el modelo de negocio de este cliente, sus procesos, el problema que se pretende resolver con la aplicación, y los beneficios que ésta puede proporcionar. Una vez entendida toda esta información, se inicia el proceso de Captura y Análisis de los Requisitos, el cual permite definir la funcionalidad que la aplicación debe proporcionar, y el entorno en el que se debe ejecutar. Es un proceso muy importante, porque permite a los stakeholders saber que los responsables del desarrollo han entendido lo que se pide.
Una vez terminada la fase de análisis de requisitos, se define la arquitectura de la aplicación, la cual establece la dirección en la que se deben tomar las decisiones clave de diseño, para asegurar que se hace lo necesario para crear un sistema que funcione.
Las empresas que se dedican a producir software saben perfectamente que lo que cuesta realmente, y lo que les permite generar beneficios, es que las aplicaciones sean fáciles de mantener. Y la condición principal y necesaria para que esto ocurra, es que las aplicaciones sean escalables, es decir, que se puedan modificar fácilmente en el menor tiempo posible. Para que esto ocurra, es absolutamente necesario que el diseño soporte los cambios en los requerimientos, y que gestione eficazmente las nuevas dependencias que puedan aparecer, ya que la gestión de estas dependencias es la causa principal que provoca la degradación del diseño de una aplicación.
Robert C. Martin introdujo el concepto de degradación aplicado al diseño de software, entendido como el proceso por el cual, un diseño original va perdiendo su esencia a medida que se producen cambios en los requerimientos. La definición de un diseño de software pasa por identificar los diferentes módulos que lo componen y, sobre todo, las dependencias entre ellos. Al principio todo cuadra y es bonito, pero puede ocurrir que los cambios se implementen sin tener en cuenta la idea del diseño original, y se hagan workarounds que provoquen que el software no sea escalable y/o sea muy difícil de mantener. Llegados a este punto, normalmente, se suele plantear un rediseño del software, el cual, si se acaba implementando, debe convivir con el software que no sólo está en producción, sino que además sigue evolucionando, con la dificultad y coste que todo esto implica.
La capacidad del software para ser mantenido es inversamente proporcional a la degradación del diseño de las dependencias.
Para evitar que todo esto ocurra, o al menos para ser conscientes de que está ocurriendo, quizás nos podríamos plantear un par de preguntas:
¿Por qué los cambios en los requerimientos de las aplicaciones de software acostumbran a provocar la degradación del diseño? Puede ser por varios motivos:
- Puede ocurrir que no se haya entendido el objetivo de los cambios, o para qué sirven.
- Con demasiada frecuencia, los cambios se implementan demasiado rápido, sin plantearse diferentes soluciones.
- Suele ocurrir, también, que los cambios los realizan ingenieros que no conocen la filosofía del diseño inicial, o los motivos que llevaron a implementar dicho diseño.
- Y aunque se conozca el diseño inicial, puede ser, que por algún motivo, se decida seguir otro camino.
Hay que tener en cuenta que los requerimientos siempre cambian, por lo que no pueden ser la justificación para explicar la degradación del diseño. Es justamente al contrario, el diseño siempre tiene que estar preparado para poder adaptarse a los cambios necesarios.
¿Existe alguna manera de identificar el inicio de la degradación del diseño?
Según Martin, cuando se habla de la degradación del diseño, en realidad se está hablando de la degradación del diseño de las dependencias y, en consecuencia, de la capacidad del software para ser mantenido. En este sentido, el objetivo principal de todo ingeniero de software, debería ser encontrar la manera de que el diseño de una aplicación sobreviva a los cambios y se proteja de la degradación. Y esto pasa por gestionar eficazmente las dependencias entre los diferentes módulos que conforman el diseño.
Martin, en su artículo “Design Principles and Design Patterns”, enumera las siguientes cuatro características del código para poder identificar un diseño degradado. Las cuatro están causadas, directa o indirectamente, por el hecho de tener dependencias inapropiadas entre los módulos.
Código RÍGIDO
El código es RÍGIDO cuando es difícil de cambiar, es decir, cuando los cambios más sencillos resultan muy complicados. Esto suele ocurrir cuando un cambio en un módulo provoca muchos cambios en módulos dependientes. Esta situación, se da cuando los módulos dependen los unos de los otros de manera inadecuada. Cuando el software se comporta de esta manera, cualquier cambio es complicado, sobre todo porque no se puede saber el coste en tiempo y dinero que va a suponer.
Código FRÁGIL
El código es FRÁGIL cuando es fácil de romper. Esto ocurre cuando al modificar una parte del código aparecen errores en otras partes, incluso sin relación conceptual con la que se está cambiando. Esta situación se suele dar, cuando los módulos dependen de estructuras de datos de manera inadecuada. El aumento de la fragilidad en el código provoca desconfianza y hace que sea muy difícil de mantener.
Código INAMOVIBLE
El código es INAMOVIBLE cuando es difícil de reusar en otros proyectos o módulos. Esta situación ocurre cuando el código está muy acoplado y tiene tantas dependencias, que al final, la cantidad de trabajo y el riesgo que supone reusarlo, es más alto que reescribir la funcionalidad.
Código VISCOSO
El código es VISCOSO cuando es más fácil implementar workarounds que mantener la filosofía del diseño existente. Según Martin, existen dos tipos de viscosidad:
- Viscosidad en el diseño
Se da cuando el camino que preserva el diseño existente es más costoso que el que no lo hace, es decir, que es más fácil hacer el cambio de la manera incorrecta que de la manera correcta
- Viscosidad en el entorno
Se da cuando el entorno de desarrollo es lento e ineficiente. Por ejemplo, si se tarda mucho en compilar se hacen cambios que minimicen el número de compilaciones.
Estos cuatro conceptos relacionados con el código, Rígido, Frágil, Inamovible, y Viscoso, permiten identificar diseños degradados, por lo que es muy importante tenerlos en cuenta a la hora de afrontar cambios en el software. Cómo puedes imaginar, existen estrategias para evitar que el código tenga estas características, y de ellas hablaremos próximamente.
Deja una respuesta