domingo, diciembre 10, 2017

Principios SOLID, una conversación


Los principios SOLID datan de principios de siglo —del nuevo, no del viejo—, y establecen unas pautas generales para diseñar software más legible, mantenible y escalable. Hasta aquí, todo bien. SOLID son las 5 siglas, de cinco principios.
“S”, de  Single Resposibility principle, o lo que vendría a ser; que cada clase debe tener una sola responsabilidad. Si es de negocio, ¡es de negocio! no debe incluir lógica de comunicaciones. Nada de andar metiendo IFs en los controladores.
La “O”, de Open/Closed principle, es decir que los objetos o las entidades, deben ser abiertas para las extensiones, pero cerradas para las modificaciones.
—¡Me perdí, a otra cosa! ¿Abiertas? ¿Cerradas?
—Entiendo. Es difícil. Y muchas veces entra en conflicto con otros patrones de diseño. Algunas veces hay clases abiertas para su modificación ¿un Proxy, por ejemplo? y otras que no, que las tienes que extender.
Que hagas las clases de modo que cuamplan con un comportamiento, y que si este comportamiento se amplía, crees otra clase para ello.
Por ejemplo, si tu jefe te pide que le cambies el comportamiento de algo, no modifiques la clase existente, ¡ya pasó testing! construye otra. Y a ésta otra, la haces heredar de la primera y pones todo el código nuevo ahí.
Crecer por agregación, no por remplazo.
—Pero, ¿y si alguna clase ya no me sirve? ¿Se ha quedado obsoleta?
—¡Ahí entra el refactoring! Mueve el código a una clase padre, estableces una nueva línea base (?) y la cierras para su modificación
“L” de Liskov Substitution Principle, ««Olé, por Barbara Liskov»».

Este principio de sustitución sostiene que una referencia a una clase padre abstracta, puede ser cambiada por una referencia a una clase “hija” sin necesidad de conocer sus diferencias. Mmm…
¡Vale! En otras palabras significa, que una clase padre no debe contener comportamientos o variables que una clase hija no pueda contener. Por ejemplo, una referencia a una variable del tipo “MedioDeTransporte”, no puede ser remplazada por otra de una clase hija, “Coche”, si la primera tuviese un método “volar”.
Sí pones comportamientos en la clase padre que no son compartidos por el 100% de las clases hijas… ¡Hay tabla! ¡Modifica tu árbol de herencia!
La “I”, viene de Interface Segregation Principle, o lo que en la lengua de Cervantes sería; romper las interfaces grandes en pequeños pedacitos. Nada de métodos @Override vacíos con TODOs que manchan la pantalla. Si tienes una interfaz general que contiene todo el comportamiento, la “Segregues” en varias interfaces pequeñitas. Así solo declarar la tarea que vas a realizar, y en un futuro cercano, reemplazar solo ese comportamiento y no todo.
Por último, la “D” proviene de Dependency inversión principle. Este principio me parece similar o tiene algo que ver con el principio “L”. Ya que hace referencia a que la interacción entre todos los módulos (controladores, servicios, repositorios de objetos, utils) deben ser del tipo interfaz o clases abstractas. Nada de clases concretas. Pero además introduce otro concepto; el que tiene que haber una clase en el medio, que cumpla con algún patrón de creación —Factory method, Abstract Factory, prototype, etc—, que sea el responsable de realizar los “new” (Instanciar los objetos)
—¡Más clases! ¡El código se vuelve imposible de seguir! ¡Cómo lo debbugeo!
—Ya, sí... en un principio se vuelve más difícil… Pero te tengo una sorpresa…
—¿Cuál?
—A todo esto último… lo realiza Spring, cuando escribes la anotación @Autowired. Tú solo preocúpate por declarar bien tus variables.
—¡Tantas clases no se justifican, la mayoría de las veces!
—Es por eso que no debes apagar el cerebro. Piensa cuáles funcionalidades pueden cambiar en el futuro y cuáles no.
—¡Las del core del negocio!
—¡Exacto! Recuerda; clases con una sola responsabilidad, interfaces pequeñas… sobre las variables; que sean interfaces o abstractas. Crece por agregación, y sobre lo último… bueno, déjaselo a Spring o analízalo con más detalle.


No hay comentarios.: