Refactorizando c贸digo aplicando Casos de Uso

Refactorizando co虂digo aplicando Casos de Uso

Deja una respuesta

Comment as a guest.

  1. Hola excelente tutorial mas bien mi duda seria como la esta la estructura de folders en tu proyectos me imagino que todos las clases de tus casos de uso estan en un folder llamado 芦UseCases禄 Y por cada m贸dulo otro subfolder llamado 芦Profile禄 Como para tu ejemplo no se si estar铆a bien de esa forma o como lo trabajas tu? Tambien por ultimo estoy confundido si casos de uso serian igual que servicios? Ya que yo toda la logica del negocio la coloco en una clase por ejemplo 芦ProfileService禄 Por eso queria saber la diferencia nose si estar铆a bien o no para aprender buenas pr谩cticas

    1. Hola Thiago, c贸mo est谩s?
      Agrup贸 por entidades. Por ejemplo, en Profile/ meter铆a todo lo relacionado con este.
      Y la segunda pregunta, si, casos de uso y servicios son lo mismo pero en terminolog铆a de Arquitectura Limpia se usa UseCase.
      Lo malo del nombre ProfileService es que no sabes que puede haber ah铆 adentro. Cualquier programador que quiera agregar una feature relacionada al Profile, seguramente la agregara adentro de esa clase. Es mejor usar Acci贸n+Entidad como lo hago en este art铆culo.

      1. Me gusto mucho el articulo, y dejo mi comentario aca dado que mi consulta es muy similar a la del amigo Thiago, y siguiendo el hilo, para ese caso recomendarias ordenar la logica que ya esta en services/ProfileService.php pasarla a un subdirectorio organizado por entidad y accion quedando de esta forma: Services/Profile/ UpdateProfile.php y GenerateAvatar.php o hay otra manera de organizar mejor la logica de negocio?

        1. Hola Jose como estas? Me alegro que te haya gustado el art铆culo!
          Lo ideal es tener Profile/Services/UpdateProfile.php (o cambiar services por UseCases). Por otro lado tener Avatar/Services/GenerateAvatar.php.
          Me parece lo mejor tenerlo as铆, no solo los casos de uso, sino tambi茅n su modelo, sus controllers, etc. De esta forma te ahorras tener las cosas separadas por todos lados.
          Si se te hace mucho trabajo hacer esta estructura de carpetas porque es un proyecto heredado, bueno, no esta mal ponerlo como Services/Profiles/[Casos de uso].

          Saludos y gracias por visitar el blog.

        2. Seria interesante que Matias muestre un ejemplo de como podrias hacer esa estructura de carpetas y ver como tener asi un proyecto limpio separando los modelos, controladores, casos, etc.

          Se te agradeceria mucho!

        3. Hola gente, gracias Matias un articulo de lujo es este. Solo me quedo una duda. la carpeta Service, va dentro del app/Http/Services o la ra铆z del proyecto? Muchas gracias!!

  2. Excelente post, espero que esto ayude a los desarrolladores a ser mejores y dejar de un lado la mediocridad, si en verdad les apasiona la programaci贸n, deben hacer el esfuerzo m谩ximo para ser mejor cada d铆a en este campo y que sea un gusto programar, ese c贸digo inicial es un desastre, no lo insulto porque todos comenzamos por ah铆, conoc铆 alguien que trabajo en una empresa donde realizan exactamente ese mismo tipo de c贸digo y no quer铆a mejorar porque as铆 estaban todos sus c贸digos y todos deben programar as铆, 贸sea promoviendo las malas practicas, a compartir este articulo se dijo aver si mejoran.

    1. Si, seguramente varios hemos empezado programando as铆. Por eso esta bueno que se promuevan las buenas practicas cuando uno las aprende.
      Muchas gracias por tu comentario.

  3. Muy bueno , algo que vi en algunos repos , es que en lugar de usar controladores , los cuales generalmente abusamos de la cantidad de responsabilidades que tiene (los explotamos con un monton de metodos) , se usan actions , seria hacer una clase por cada metodo por ejemplo CreateUserAction , esta clase tendra sus dependencias, junto con su logica y sera mucho mas facil de leer y manejar . Y estaremos cumpliendo con Single Responsibility Principle

    1. Como va Marcelo? Exacto, son lo mismo. En otro lados lo llaman Services tambi茅n, pero el fin es el mismo.
      A m铆 me gusta UseCase porque es el mismo lenguaje que usan otros sectores de la empresa, por ejemplo, an谩lisis o QA. Si a un analista le hablas de Actions o Services no te van a entender. Pero s铆 les hablas de 芦casos de uso禄 sabr谩 exactamente a que te estas refiriendo.

  4. Hola Matias, muy bueno el post.
    Ta hago una consulta, estoy reestructurando una app que tuve que hacer a los ponchazos ya que el cliente necesitaba empezar a vender y bueno esta muy atada con alambre, entonces empece a leer un poco sobre como ordenar todo un poco y hacer mejor las cosas, ya que estoy laburando solo en esto por el momento y por ahora yo lo entiendo, pero se me va a hacer mucho lio.
    Bueno el tema es el siguiente, estoy tratando de aplicar un poco ddd, no a fondo, siguiente la estructura de laravel, y desacoplando lo que hice como service, que imag铆nate tengo un service por modelo y es un lio barbaro.
    La pregunta en si es la siguiente: estoy armado el action para crear una orden, como esta en el ejemplo, con la funci贸n execute que recibe el request y el customer, pero necesito devolver la orden para usarla en el controller y hacer un redirect al show de la orden. Me conviene hacer un return en el execute o podr铆a agregar un m茅todo getOrder() para que una vez creada la llamo as铆 , perd贸n por lo extenso. Muchas gracias.

    1. Como est谩s Mariano?
      No te hagas problema porque es bastante com煤n hacer un sistema a los ponchazos, ver si es redituable y reci茅n ah铆 empezar a atender la deuda t茅cnica que dejamos.
      Con respecto a la pregunta, por ahora no estar铆a mal que execute devuelva la orden. Cuando empieces a implementar DDD puede que tengas que hacer una modificaci贸n para esto. Pero te va a llevar un segundo porque ya vas a tener todo ordenado. Por ahora anda paso a paso como estas haciendo.

      Suerte y cualquier cosa volve a darte una vuelta por ac谩.
      Saludos.

  5. Hola, al igual que tus otros post, este esta genial muy bueno.
    Solo una pregunta en la clase UpdateProfile, en m茅todo publico inyecta el request, esto no genera dependencia de lo que venga en el request, ese decir no se le deber铆a pasar como parametro todo lo que vaya a necesitar el m茅todo?…Por ejm hay una clase StoreVenta, esta me permite guardar una venta desde un erp(guarda venta, factura, comprobante, etc), ahora se esta desarrollando un POS(otro frontend), y desde ah铆 tambi茅n se realiza venta y esta se debe guardar de la misma manera en como se guarda en el erp…Mi pregunta, desde el pos podria llegar la data de una manera distinta, entonces el m茅todo(que guarda la venta del erp) de la clase creada ya no me sirve…o como podr铆a ser la estructura, para tener solo un m茅todo que se encargue de guardar una venta, venga del erp o pos, o desde una app quizas y que vayan a tener maneras distintas en como llega el request.
    Saludos y gracias de antemano.

  6. Me uno a los amigos que dicen que ser铆a bueno un articulo sobre estructura de tus aplicaciones y donde poner cada cosa.

    Esta p谩gina vale oro :), gracias por todo .

  7. S煤per buena la explicaci贸n muchas gracias, como puedo acceder al articulo que dice ah铆 que contin煤a y que habla sobre testeabilidad.

  8. una pregunta, por ejemplo para un listar de productos….es necesario crear una clase useCase para eso? o en el controller puede inyectar por ejemplo el repositorio y llamar al m茅todo que trae el listado de productos?

      1. la interfaz, pero es lo correcto eso?, puedo inyectar el repositorio directamente?….es que yo pienso que todo tiene que ir controller -> servicio -> repositorio, pero tambi茅n lo veo innecesario un useCase(o servicio) para el listar…Lo hize asi, pero vi que en el servicio solo pasaba los mismos parametros al metodo del repositorio. Tengo esa duda o como seria en casos donde no hay logica de nogocio, ejm: un listar, no tiene logica todo viene directo de un script sql…Espero se entienda, gracias

        1. Hola Artura, disculpa la demora en contestar.
          Si, los casos de uso son l贸gica de negocio. Si solo necesitas obtener los registros y devolverlos, no hace falta que crees un UseCase.

  9. Hola Matias, me encant贸 el articulo. Tengo una duda en mi proyecto: al desarrollar el caso de uso ‘Invitar usuario a grupo de trabajo’, este se subdivide en 3 casos seg煤n si el usuario no est谩 registrado, est谩 registrado pero no tiene perfil adecuado, est谩 registrado y tiene perfil. Deber铆a crear 3 nuevas clases para estos ‘sub-casos de uso’? O realizar toda la logica en el casu de uso principal con metodos privados?

    1. Hola Juan, como estas?
      Lo podr铆as hacer como m茅todos privados si son simples. Pero lo ideal ser铆a que los modeles en 3 casos de uso separados.

      1. Perfecto, otra duda que me surgi贸 es como manejar los errores. Si falla algo en los servicios (por ejemplo, usuario ya agregado al grupo de trabajo), como le advierto al controller?

        1. Muy buena pregunta Juan! Fijate que el controller ejecuta los casos de usa dentro de un try/catch, por lo tanto, siempre que haya un error tenes que lanzar una exception y el controller ser谩 el encargado de handlearlo.

  10. Buenas tardes Matias, tengo una peque帽a duda en un hipotetico caso de uso createProduct.
    El controller ejecutar铆a el servicio de la siguiente forma: $this->productService->create($data);
    Est谩 bien que el servicio tenga un atributo privado de tipo Product inyectado en el constructor?
    Es decir, est谩 bien que el servicio haga un $this->product->save() luego de asignar los datos al producto ($this->product->fill($data))? O deber铆a hacer un new Product() en lugar de tener el producto como un atributo del servicio?
    Espero se entienda la consulta, saludos!

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