El mantra anti-código espagueti (II)

Gonzalo García03-Ene, 2020

En la primera parte de este artículo se veía el contexto de los principios SOLID como un mecanismo de una serie de principios o buenas prácticas para evitar, de alguna forma, crear código espagueti. Los principios que se tocaron fueron:

  • Principio de única responsabilidad (Single responsibility)
  • Principio de abierto/cerrado (Open/Closed)

Lo cierto es que este es sólo el comienzo del acrónimo SOLID y se quedaron pendientes de ver los últimos tres principios:

  • Principio de sustitución (Liskov substitution)
  • Principio de segregación de interfaces (Interface segregation)
  • Inversión de dependencias (Dependency inversion)

Vamos a ver cada uno de estos tres principios y después nos adentraremos de otros grandes conocidos como KISS, YAGNI o DRY.

Principio de sustitución (Liskov substitution)

El principio de sustitución de Liskov se basa en la herencia de clases y los comportamientos de los hijos. En concreto, indica que si en alguna parte del código se está utilizando una clase (y esta es extendida), se debería poder sustituir cualquiera de las clases hijas o herederas y que el código siga funcionando correctamente. Esto obliga a asegurarse de que cuando se extiende una clase no se está alterando el comportamiento de la del padre.

Sintomatología asociada

Algo habitual suele ser crear una clase que extiende de otra en la que algunos métodos del padre no son de ninguna utilidad. La opción adecuada sería segregar los métodos del padre en distintas unidades lógicas por clases distintas.

En realidad, la opción rápida, y que rompería este principio, sería implementar el método que no sirve sin ningún comportamiento o bien lanzar una excepción cuando se use. Esto no es ni limpio ni robusto, pues dependiendo de las clases hijas que se instancien y sobre las que se pasen los tests, el programa lanzará excepciones innecesarias y dispares entre las clases hijas. Esto se traduciría en mala praxis del principio y, por ende, una mala jerarquía de clases.

Principio de segregación de interfaces (Interface segregation)

Este principio dice que si la clase en la que se va a implementar una interfaz no utiliza la totalidad de los métodos de la misma se deben separar la lógica de esta en más interfaces.

Exactamente igual que en el principio de sustitución, en el cual se apoya al menos en concepto, ocurrirá que las clases hijas de interfaces mal segregadas terminarán implementando esos métodos que realmente no necesitan con excepciones o un
return ‘’, lo cual hará que el software en conjunto no sea robusto. Esta es una herramienta más para decidir cómo segregar las interfaces en base al núcleo de la aplicación o a las reglas de negocio del software que se esté desarrollando.

Principio de inversión de dependencias (Dependency inversion)

Depende de abstracciones, no de implementaciones

Este principio será el que más presente se tenga en el día a día si se quiere un código testable y sostenible. Gracias a él se puede hacer que el código, que es el núcleo de una aplicación, no dependa de los detalles de implementación, como pueden ser el framework utilizado, la base de datos o la forma de preparación de la caché de los datos.

Todos estos aspectos se especificarán mediante interfaces y el núcleo no tendrá que conocer cuál es la implementación real para funcionar.

¿Es el camino correcto?

Este principio es fácil de evaluar: si hay una complejidad de instanciación de clases dependientes o si es realmente complejo testar una clase por las implementaciones que tiene, significa que hay algo que no se está haciendo bien. Hay que mantener la lógica abstracta y sencilla. En cuanto a esto, a continuación se verá KISS, una herramienta que refuerza este principio.

Más herramientas: KISS, DRY y YAGNI

Estos principios son muy sencillos y arrojan mucha luz en el debate diario sobre cómo afrontar un proyecto o nuevo módulo de una aplicación.

¿Qué es KISS?

Es un acrónimo de la frase Keep it simple, stupid!

Aunque su propio significado habla por sí mismo, lo que viene a decir este patrón es que la sencillez tiene que ser una meta en el desarrollo y que la complejidad innecesaria debe ser eliminada. Se debe abandonar lo complejo. Si uno mismo no puede explicarlo de forma sencilla significa que está mal planteado.

¿Qué es DRY?

Quiere decir Don’t repeat yourself.

Básicamente, no hay que repetir funcionalidades. Es sencillo: si se tiene, por ejemplo, un método para calcular un presupuesto y, posteriormente, hay que agregar al cálculo un envío de email con el presupuesto calculado, no se debería copiar el cálculo e incluirlo en el método que lo envíe antes de hacerlo. Habría que independizar el cálculo a modo helper o servicio y llamarlo donde se necesite. De este modo, si la fórmula que se aplica cambia en algún momento no habrá  que cambiarlo en todos los sitios que lo necesitaste, solo en ese helper/servicio.

¿Qué es YAGNI?

Este acrónimo significa You Aren’t Gonna Need It (no vas a necesitarlo) y es uno de los principios del Extreme Programming, que indica que un programador no debe agregar funcionalidades extras hasta que no sea estrictamente necesario.

Aplicar siempre las cosas cuando realmente los necesita, no cuando lo que prevén que los necesita. – Ron Jeffries

Conclusiones finales del mantra anti-código espagueti

Aunque puedan parecer ambiguos algunos principios SOLID, incluso repetitivos entre ellos, lo cierto es que tratando de pensar en su forma de guiar, se conseguirá una rutina de trabajo en la que, de forma automática y poco a poco, se organice un código de la manera más limpia y teniendo menos mantenimiento asociado al proyecto.

Siempre sin volverse loco, pues aunque estos principios existen para ayudar a la toma de decisiones se darán situaciones en las que no se pueda ser del todo correcto. Habrá que adaptarse al medio y a los cambios, por lo que lo más inteligente será tratar de implementarlos en el día a día de una forma saludable.

 

Gonzalo García

Lead Software Developer & Product Management