Guía definitiva de Principios SOLID – Explicados con Laravel

Guía definitiva de Principios SOLID - Explicados con Laravel

Deja una respuesta

Comment as a guest.

  1. Después de leer esto me doy cuenta que programar bien no es tan sencillo como aprender un lenguaje jaja es complicado estar pensando a cada paso que das si no estás incumpliendo uno de los principios de SOLID. Quisiera saber realmente que porcentaje de los programadores aplica SOLID

    1. Aprender un lenguaje es la punta del iceberg si queres ser un desarrollador profesional. Y los principios SOLID son el comienzo, hay mucho más todavía.
      Con respecto a aplicar siempre SOLID es relativo, depende lo que estés haciendo. Si estas haciendo un blog bueno…no hay problema. Pero si estas haciendo una plataforma mucho más grande, que será el núcleo de tu negocio, en ese caso sería clave aplicarlos.

    2. Se te dificulta en este momento porque algo que no te cuentan es que para aplicar estos principios requieres el uso de pruebas de unidad con TDD o BDD, intentar aplicar esto con pruebas manuales; creeme que es complejo y una perdida de tiempo. Lo que ocasiona que los desarrolladores nuevos se frustren y regresen a las practicas que ya conocen. Poro otro lado algo que no te dicen es que solid nacio de la aplicación del conocmiento en sistemas grandes y complejos y de la necesidad de tener limites bien definidos entre los elementos de software para reducir su acoplamiento para reducir su complejidad. Así que no es necesario que apliques todos los principios, Ahora ¿Cómo sabes que principos aplicar? haciendo uso de pruebas unitarias y dependiendo del problema.

        1. La razón la explique en mi mensaje anterior. Aplicar los principios a una sola clase es mediamente sencillo pero el detalles es que en proyectos reales los objetos colabora entre si y aplicar los principios y tener todo funcionando es mucho mas sencillo si usas TDD que hacer uso de tecnicas manuales que consumen mucho tiempo. Te unvito a que hagas un ejemplo medianamente grande y apliques los principio de la forma clasica y luego intenta haciendo uso de TDD y me cuentas lo resultados. Por otro lado el uso de pruebas automatizadas no es opcional, son necesarias siempre, es algo que debes de manejar si quieres crear software mas confiable.

    1. Como poder, podrías. Todo depende el caso. Pero tene en cuenta que una clase engloba un concepto.
      No esta mal que una clase de tipo Resources Controller tenga sus correspondientes métodos index(), create(), store(), update(), etc. Pero no deja de ser un Controller, su concepto y su responsabilidad es la de recibir una request, delegar y responder al cliente o vista. Cualquier duda, volve a escribir :).

      1. Matías tu dices: «El concepto del Controller y su responsabilidad es la de recibir un request, delegar y responder a una vista».

        Yo creía que el Controller es el que hacía todo. El Model se encargaba de la DB, las VIEWS de la Interacción con el Cliente y el CONTROLLER de procesar lo que recibe de los forms, consultar al Model procesar y mandar a vista. Ahora resulta que el controller sólo Delega jajaja …

        1. Hola Mauro. Si, es muy común ver que las personas que utilizan Laravel ponen toda la lógica en los controladores y luego te surgen preguntas como «Como puedo llamar un método de un controller desde otro?». También, si quisieras utilizar esa lógica pero ahora en un controller de una API o de un CLI, deberías crear un nuevo controller y hacer copy&paste de esa lógica. En resumen, no podes reutilizar código.
          Por eso, lo mejor es separar la lógica de negocio en clases separadas. Saludos.

    2. depende del caso, no es conveniente usar single action controllers (SAC) si estás haciendo un clásico CRUD/ABM de productos (terminarías con 4 o más SAC)

  2. Solo un comentario, tu primer ejemplo no viola SRP porque el controlador no esta manejando directamente la validación ni la inserción, esta llamando a otros objetos que se encargan de eso (Request, Model). Lo que estas haciendo en tu ejemplo, es hacer que el método haga una sola cosa; un cocepto que viene explicado en el libro de Clean Code que estas recomendando, pero aun así, tampoco se viola ese principio porque las llamadas a los otros objetos estan en el mismo nivel de abstracción, pero es valido reactorizar para hacer mas legible el método.

    1. Discúlpame, pero no estoy de acuerdo.
      En el primer ejemplo el controlador esta instanciando los objetos Request y User donde cada uno de los respectivos objetos están haciendo sus tareas dentro del método del controlador, no hay delegación de tareas.
      Cuando necesites cambiar/agregar una validación o la forma en que guardas los datos, deberás tocar la clase Controller y chau SRP.

      1. Con ese argumento estas confundiendo OSP con SRP. porque para agregar o cambiar la validación tienes que modificar el método, pero no lo haces en el controller si no en el request. Con lo cual no estas afectando la responsabilidad del controller. Si falla la validación se genera el response o en todo caso se lanzara una Exception; que tampoco genera el Controller y por lo tantno no afectan la responsabilidad. SRP se trata de lo que hace el objeto y en este caso no se viola: porque existen otros dos objetos Resquest, Model y Response que se enargan de hacer lo que no debe de hacer el controller. Ahora desde el momento en que llamas o invocas a otro objeto dentro de una clase, ya es delegación. En el libro de Erich Gamma (Patrones de diseño) que recomiendas viene un capitulo que habla sobre el tema. En resumen tu ejemplo no viola SRP, pero si OSP porque tienes que hacer cambios en el controller para modficar las validaciones de las cuales no se hace cargo el Controller, de hecho ni el request, y una forma de resolverlo es como lo hiciste. Tu articulo es muy bueno y m sugerencia es que ajustes tu ejemplo inicial.

        1. Yo creo de que si se está violando el principio de responsabilidad única. Porque el método haciendo de todo

        2. Disculpa Hermenio pero te estás equivocando. Si bien OCP es parecido a SRP, el principio que dice que una clase debe tener solo una razón para cambiar, es el principio de responsabilidad única. Y en el primer ejemplo tenés más de una razón, más responsabilidades y más acoplamiento, por lo tanto, claramente está violando SRP. Saludos amigo y muchas gracias por tus comentarios sobre el artículo.

        3. SRP se trata de lo que hace la clase pos si misma, es decir lo que afecta su estado interno y en ningun lado el controller tiene la logica para validar, responder y mucho menos, insertar datos por si misma, si eso sucediera entonces si estas hablando de SRP pero en tu ejemplo no sucede esto; porque otras clases estan encargadas de gestionar la validación (Request), La inserción (Model) y la respuesta json (Response) eso no es SRP hijo. Lo que tu estas resolviendo en tu ejemplo es acoplamiento que es otro tema que sucede entre un objeto y sus dependecias. y OSP porque un cambio en las validaciones me obliga a cambiar los parametros en el Request validation y eso me obliga a pensar en una forma de poder agregar o quitar validaciones sin tener que tocar el controller. Para finalizar generalmente una clase que viola SRP sufre de Cambio Divergente (Divergent Change) otra forma de darte cuenta es aplicar GRASP.

        4. Sigo sin compartir tu forma de verlo, pero bueno…dejemos que los lectores se interesen en el tema y saquen sus propias conclusiones, que ese es el fin del artículo. Saludos.

  3. Tu explicación es muy clara y sencilla lo que hace que pueda entenderla (siendo esto muy difícil para mi jajajja), hoy en la mañana empece a implementar tus enseñanzas, muchas gracias por la información.

    1. Hola Jaime.
      Para mí, la mejor opción es crear una carpeta con el nombre de tu proyecto/modulo en la raíz del proyecto y registrar el namespace en el archivo composer.json. En esta nueva carpeta aplicas lo viste y según las necesidades. Luego, desde el controlador haces los llamados a lo que necesitas.
      En un próximo articulo voy a entrar mas en detalle.
      Saludos.

      1. Siguiendo el hilo del amigo Jaime, tienes un articulo sobre la estructura mas correcta para saber como tener bien estructurado mejor mi proyecto.

  4. De antemano muy buen artículo gracias, quisiera saber si tienes un repositorio público donde se hagan aportes a buenas prácticas y el uso de SOLID con Laravel.. Gracias.

    1. Hola Giovanny. Muchas gracias por tu comentario. No por ahora, solo los artículos que están disponibles en esta web. Pero voy a empezar a subir algunos ejemplos a mi repo.

      Saludos.

  5. Excelente artículo, bien explicado y con ejemplos muy sencillos. Es un buen punto de partida para todos aquellos desarrolladores que de alguna u otra forma queremos mejorar en las técnicas apropiadas para un código limpio, escalable y mantenible. Gracias por el aporte de tus conocimientos.

  6. Hola. Excelente artículo. Te consulto, en el primer ejemplo, cuando agregas UserRepository como parámetro al método store, lo inyectas como servicio (registrando un service provider y bindeando)? Gracias

  7. muy buen articulo, tengo una duda espero me la puedas aclarar.. en el ultimo ejemplo si quiero utilizar digamos las 3 clases (UserEloquentRepository, UserSqlRepository, UserCsvRepository ) en diferentes partes de mi código. como tengo que bindear esto en mi proveedor de servicios? como saber cual de las 3 clases es la que quiero instancear en determinado lugar?

  8. Excelente la verdad estos teman caen como anillo al dedo.
    ¿No has pensado en hacer un tema sobre POO con PHP?
    Gracias por todo el contenido que suben, un abrazo!!!

  9. tengo que registrar en services provider el controlador repository del primer ejemplo para que funcione? porq me dice que laravel no encuentra /repositories

    1. Como estas Ariel?
      Es correcto pero ahora el switch lo estamos usando para devolver distintas clases que ejecutan formas de pago.

      Al principio lo que hacia el switch era decidir que forma de pago se iba a ejecutar, que eran formas de pago que estaban codeadas dentro de la clase Payment y si querías agregar o quitar una forma de pago, tenías que tocar la clase Payment y el método pay() para agregar esta nueva forma de pago.

      Al aplicar el patrón abierto/cerrado lo que nos permite es no tocar la clase Payment, ni el método pay(). Unicamente crearíamos una nueva clase para la nueva forma de pago y la agregaríamos en el switch de la factory.

      Como devs siempre deberíamos intentar crear nuevas clases en lugar de modificar las que existen. 😉

      1. Hola Matias, aplique el principio de Abierto/Cerrado, pero tengo una duda, yo utilizo el método pay como metodo POST para pasarle el request con el type y otros datos necesarios y allí utilizo 2 métodos paypal y Strapi, pero cuando hago la llamada al factory para que haga el trabajo el switch, no consigo que me haga el return del link para pagar de paypal ni de strapi, que me recomiendas?

        1. Ya conseguí mi error, como es una arquitectura un poco distinta hay que analizarla para comprenderla bien, excelente post muchas gracias.

  10. Excelente para aprendizaje, como dicen abajo, cometemos muchos errores y mas cuando seguimos video cursos y mayoria no explican estos principios que al Parecer «Reglas» son en realidad ayudas para hacer las cosas crecer, porque creas tu proyecto pensabo en las rutas web.php y todas la respuestas en tus controllers van como corresponden a la vista respectiva pero si luego vas a conectar una app, utilizas api/controller y tener que empezar a duplicar el codigo no es viable, porque al cambiar un field «desastre» entonces en este Caso para proyectos sencillos en mi humilde opinion pueden usar Traits que facilitan esto si implementar solid del todo.

    1. Muchas gracias por tu comentario Jonay! Personalmente no me gustan los traits, a menos que sea requerido para un caso puntual. Pero tienes mucha razón con lo que comentas sobre la duplicación de código y como las buenas prácticas nos pueden ayudar a evitarlo.

  11. Otro gran articulo. No puedo tener adceso a los libros que mencionas, asi que me toca implementar cada uno de sus ejemplos para iteriorizar de manera correcta los principios de SOLID. En algo concuerdo con algunos comentarios. Muchos de los videos e informacion que consigues de forma libre no tienen en cuenta ninguno de estos conceptos, te das cuenta cuando te enfrentas a proyectos reales o quieres ingresar en alguna empresa la cual revisa tus códigos. Muchas gracias por compartir.

Sliding Sidebar

Matias Echazarreta

¡Hola!

Mi nombre es Matias Echazarreta.
Soy desarrollador web con más de 12 años de experiencia. Amante de Laravel, de los libros y del rock de los ’90. Te puedes comunicar conmigo  por trabajos de contratación, haciendo click aquí.

Nuestro Patreon

Desde Patreon puedes solicitar asesoria personalizado. ¡Ir a Patreon!

Suscríbete a nuestra lista de correo