Mejora la Calidad de tu Código utilizando Value Objects

Ғылым және технология

El patrón Value Object es uno de los más famosos en cuanto a Diseño de Software, pero también uno de los más odiados.
Curso de Value Objects! bit.ly/curso-vo
Es criticado porque nos induce a "classitis" y porque añade complejidad al código, pero, en nuestra opinión, los beneficios compensan de forma desmesurada a sus contraprestaciones.
En este vídeo te demostramos que programar con Value Objects acaba simplificando mucho tu código
﹤🍍﹥ CodelyTV
├ 🎥 Suscríbete: kzread.info?sub_co...
├ 🐦 Twitter CodelyTV: / codelytv
├ 🧔🏻 Twitter Javi: / javiercane
├ 💂‍♀️ Twitter Rafa: / rafaoe
├ 📸 Instagram: / codelytv
├ ℹ️ LinkedIn: / codelytv
├ 🥋 Academy: codely.com/academy
└ 📕 Catálogo cursos: bit.ly/cursos-codely

Пікірлер: 55

  • @ciltocruz
    @ciltocruz Жыл бұрын

    No suelo comentar mucho, pero hay que decir que la presentación del código, cómo cambian las diapositivas y la explicación a medida que va ocurriendo ha sido BRILLANTE.

  • @felixinit
    @felixinit8 ай бұрын

    Que forma tan pro de llevar al siguiente nivel la programación. Es el tipo de formación que deseo para mí. Una vez comprendido lo básico de programación uds son el siguiente paso lógico en nuestra formación.

  • @art_bat
    @art_bat Жыл бұрын

    La expresión regular del email debería ser estática, para no hacer que el motor JS tenga que compilar la misma expresión una y otra vez en cada instanciación de value object

  • @JorgeDev92

    @JorgeDev92

    Жыл бұрын

    A mi ya de entrada me parece extremadamente raro tener que validar tan profundamente que el email es un email y además validarlo en el momento de su creación y durante el resto de su vida, como si alguien fuese a coger la bdd y a romperla, normalmente yo valido estos inputs lo más pronto posible en el tipico middleware de validación. En clases tan chorras como las que mencionan en sus ejemplos tal vez no es evidente, pero instanciar 150 propiedades (que pueden repetirse si es un array de objetos) de un modelo bien complejo (por ejemplo, nuestro order tiene de todo, cupones, descuentos a nivel de pedido, a nivel de transporte, a nivel de producto, todos los datos de producto congelados el dia de la creación, etc...) no es gratis, es la diferencia entre que una petición gaste 1MB de ram o gaste 10MB, por no hablar de que la ram irá subiendo más rápidamente y hará falta mas GC, si encima esta ram sube tan rapido que no puede limpiarse con 3GC de vida corta (rapido) entraran en el GC de vida larga (lento), además de lo evidente, hacer new es más CPU, en un objeto no es apreciable, en un proceso que use muchos de estos objetos tal vez el tiempo y la ram pasen a ser un problema. Si tuviese que seguir este patrón lo haría solo donde hace falta y solo cuando hace falta, es decir, si me viene de la bdd debería de suponer que la base de datos no está rota, ya que si al guardar has validado no tiene porque romperse mágicamente. Otra cosa que es bastante evidente es la polución que hay en el codigo, cada propiedad tiene la propiedad en la clase, el getter, el setter, la propiedad en los parametros del constructor, la propiedad que setean en el constructor, osea, por cada propiedad vienen a ser tranquilamente 12 lineas de código, que de nuevo, no se aprecia bien dado el tamaño de la clase, pero ya se intuye, con solo 3 propiedades el codigo no les cabe en la pantalla, imaginate el ejemplo anterior, recordemos que tener ValueObjects no es la única manera de hacer una validación, perfectamente si no quieres ensuciar la clase lo puedes sacar fuera con funciones exactamente de la misma manera que los ValueObjects y usarlos cuando hace falta, que no tiene porqué ser necesariamente en el constructor, donde se ejecutará en cada instanciación

  • @lococba84

    @lococba84

    Жыл бұрын

    @@JorgeDev92 Por eso la programación con paradigma mas funcional está ganando la pulseada, yo ahora estoy explorando la arquitectura vertical slice, donde si bien hay acoplamiento permite generar responsabilidad única por cada funcionalidad que se desarrolle y es mas flexible ya que si hay que aplicar DDD también es posible.

  • @gurugamer176

    @gurugamer176

    Жыл бұрын

    @@lococba84 siempre ha sido el vencedor

  • @gurugamer176

    @gurugamer176

    Жыл бұрын

    eso deberia estar separado en una clase de validacion, por otra parte no se compila sino se interpreta en este caso de js...

  • @carlossolorzano505

    @carlossolorzano505

    7 ай бұрын

    @@lococba84 Hola, me parece super interesante y valido este punto. De casualidad tienes algún ejemplo que puedas compartir para terminar de entenderlo?

  • @Ak4n0
    @Ak4n010 ай бұрын

    Me impresiona que todos esto 'modelos' o 'arquitecturas' es hacer lo que has hecho toda la vida solo que alguien le ha puesto un nombre elegante.

  • @matiasjaime3443
    @matiasjaime34439 ай бұрын

    INCREIBLE la calidad del video Super claro

  • @jmanuelcorral
    @jmanuelcorral Жыл бұрын

    Buenas introducción, me ha encantado! la unica pega es que personalmente no me gusta que un value object devuelva excepciones. Ya que imaginemos que incumples varias validaciones con ello dentro de un ValueObject, sólo la primera que ocurra será la que haga early exit del objeto. Vi otro video en el que usabais EITHER como monada y creo que vi otro con Results... si los combinais y haceis un metodo create estático (poniendo constructor a privado), tendríais lo que buscais pero devolviendo "un tipo de resultado que no es una excepción". Eso es muy util por ejemplo cuando has de devolver resultados que no son "totalmente correctos" o "totalmente falsos", por ejemplo imaginad un alta de un usuario en el que faltan ciertos datos del usuario para hacer ciertas operaciones, puedes tener "warnings" para esos casos de uso...

  • @CodelyTV

    @CodelyTV

    Жыл бұрын

    Ahí diferenciamos el tratamiento de validaciones de cara al usuario, como lo sería el formulario que comentas, de lo que entenderíamos cómo garantizar esas reglas de integridad. Es decir, en el punto en el que estamos sí entendemos cómo excepcional que nos llegue un valor incorrecto, pero antes, en la capa del controlador por ejemplo, sí meteríamos las validaciones que comentas enfocadas a mejor UX 👼

  • @tuttodev
    @tuttodev Жыл бұрын

    Excelente video, primero felicitarlos, una pregunta, que pasa si un value object no solo tiene un value sino más de uno ? es decir por ejemplo el value object credentials en donde tenga userName y userPassword como value object ? es más que pasa si el value userPassword sea otro value object llamada Password

  • @r.amilcarrivasmarquez2892
    @r.amilcarrivasmarquez2892 Жыл бұрын

    Mejoran con los años... En hora bueno. Me ha servido mucho está clase

  • @thisisaavv
    @thisisaavv Жыл бұрын

    Gracias por estos videos. 🙋🏽‍♂

  • @arialapps
    @arialapps8 ай бұрын

    Gracias por el contenido, muy bueno!! Una mejora que veo es no colocar las validaciones y excepciones en el constructor de VO, el constructor debería estar limpio, por lo tanto, crearía un método estático "Create" en el VO donde valido y llamo a mi constructor privado.

  • @NulledExp
    @NulledExp Жыл бұрын

    Grande chicos grandes excelente todo su contenido como siempre

  • @victrio1996
    @victrio1996 Жыл бұрын

    tengo una duda respecto al uso del patrón repository, en este caso se llama al repositorio desde la capa de aplicación, yo acostumbro a inyectar el repo en la entidad del dominio y desde ahí hacer el registro.

  • @crayder03
    @crayder035 ай бұрын

    ¿con que programa hacen las presentaciones?

  • @oscarsanchez5530
    @oscarsanchez5530 Жыл бұрын

    Uaahhhh!!!! !buenisisisisisimo vídeo!!!!!!

  • @esteam
    @esteam8 ай бұрын

    Corríjanme si me equivoco pero no que inversión de control es cuando se le pasa el control de las instancias a otro?, generalmente un framework, creo que se refieren a IoC como a inversión de dependencia.

  • @dtito1991
    @dtito1991 Жыл бұрын

    Creo que ni bien vi el video me falto costo entrar en ritmo con "userRegistrar" y un metodo "register", tal vez más coherencia con todo ingles o español.

  • @oscargalvez4
    @oscargalvez4 Жыл бұрын

    Iba a preguntar por qué no recibir los value objects desde fuera (yo personalmente le veo más ventajas siempre que se haga bien y sólo para las capas de dominio y aplicación), pero ya veo que lo comentáis en el curso. Así que habrá que activar la cuenta. 😂

  • @CodelyTV

    @CodelyTV

    Жыл бұрын

    Tú sí que sabes!! 💪

  • @Paul7Peterson
    @Paul7Peterson Жыл бұрын

    Se puede hacer lo mismo con tipos en TS. type UserId = number & { __type__: 'UserId' }

  • @ChaloCode
    @ChaloCode Жыл бұрын

    Excelente video, me ayuda un monton!! pregunto sus cursos los tienen para JAVA?

  • @norbertocontreras4725

    @norbertocontreras4725

    Жыл бұрын

    siempre codean en typescript, solo un par de videos lo hace con Java

  • @carlosdavila4999
    @carlosdavila4999 Жыл бұрын

    Y que pasa cuando el valueObject es otra clase, por ejemplo Factura -> detalle ?

  • @JSneider05
    @JSneider05 Жыл бұрын

    🔥 Buen video, a activar esa cuenta. Me gusta este patrón y lo aplico en mis proyectos tal cual. Pero me he enfrentado al problema de que algunos campos del objeto de dominio son opcionales (se actualizan en flujos posteriores de la aplicación). ¿Cual seria la buena práctica para manejas VO opcionales pero mantener esas validaciones dentro del VO? Recomendaciones?

  • @felixmontalico2735

    @felixmontalico2735

    9 ай бұрын

    Lo que yo hago es que el valor del Value Object pueda ser nulo, para que no se rompa las demás validaciones siempre verifico que no sea nulo. Por ejemplo, si el email es opcional en el ejemplo del video quitaría la validación de ensureValueIsDefined y en la validación de ensureIsValidEmail añadiría una verificación de que si value es nulo se omite dicha validación.

  • @barrenaedu
    @barrenaedu6 ай бұрын

    en el constructor de UserEmail haria la asignacion luego de los ensure, osea: constructor() { this.ensureValueIsDefined(value); this.ensureIsValidEmail(value); this.value = value} ya que utilizan parametros en los ensure. Caso contrario se podrian eliminar los parametros, asignar this.value = value y luego llamar a los ensures sin parametro. Pero el primer caso me gusta mas, no se que piensan uds. Saludos

  • @jesusledesma895
    @jesusledesma895 Жыл бұрын

    Hay algo que me gustaria plantear, supongamos que estamos en un contexto de clean-architecture, si tengo validaciones que necesitan usar librerias externas estoy poniendo en mi dominio esas librerias que deberian estar en una capa superior (A menos que armemos alguna interfaz para comunicarnos con esa libreria y que usemos desde la clase de dominio) Otra opcion que yo veo, es crear una clase builder, un UserBuilder que dentro llame a 3 ValidationService (uno para cada property). Luego para solventar que el mail se pueda modificar tendriamos un UpdateUserUseCase, donde un metodo seria updateMail en cual dentro tambien llamaria al mismo ValidatonService Todo esto lo planteo con el objetivo de no llenar mi Clase User con libreria externas, ya que User es de mi dominio

  • @diegoperez6575

    @diegoperez6575

    Жыл бұрын

    Hola, en mi caso suelo usar interfaces que encapsulen las funciones de la librería en algunos casos (por ejemplo date-fns) y en otros (lodash), acabo metiendo directamente el import en la clase del dominio. La verdad es que si se quiere ser 100% ortodoxo con la clean arch, debería ir todo a infraestructura y usar interfaces para desacoplar de las implementaciones reales, pero muchas veces lo asumo por conveniencia. Asumo el riesgo de no ser 100% ortodoxo y de tener ese acoplamiento que me supone por contra menos trabajo que andar montando una interfaz para una llamada a un método de lodash. Al final estas arquitecturas son una filosofía y si se quiere ser 100% estricto, muchas veces se complica demasiado el asunto o se pierde mucho más tiempo. Aunque más que perder, yo diría que quizás pueda ser empleado de forma más productiva en otra parte de la aplicación, como test unitarios, test integrados, alguna refactorización, etc...si tienes tiempo infinito y estás 100% agusto con lo que tienes, pues ahí a tope con la clean arch siempre.

  • @ESArnau
    @ESArnau Жыл бұрын

    Habria que añadir el hashtag en los private tambien o no seria necesario? Para que sea 100% privado

  • @Paul7Peterson

    @Paul7Peterson

    Жыл бұрын

    TypeScript te lo va a respetar si no haces castings o cosas que no debes, por lo que en la práctica van a ser privados para TypeScript, pero accesibles si no van con el "#".

  • @erickgabrielcampuzanotorre1838
    @erickgabrielcampuzanotorre1838 Жыл бұрын

    que fuente y que teman usan en la muestra de codigo?

  • @CodelyTV

    @CodelyTV

    Жыл бұрын

    Aquí toda la info kzread.info/dash/bejne/ZpWi0cZvo7anfKg.html 🙂

  • @gopher9879
    @gopher9879 Жыл бұрын

    Esto sería el equivalente a crear un tipo personalizado de go y darle métodos

  • @xxnurioxx
    @xxnurioxx Жыл бұрын

    Es mucho más reutilizable, mucho más mantenible y muchísimo más simple, crear validadores externos a los modelos que hacer toda esta liada. 🥺😜🤗

  • @lupaco26
    @lupaco26 Жыл бұрын

    Actualicen Codely Theme para vscode 😢😢😢 he comprado dank mono y luce genial pero podría ser mejor

  • @Paul7Peterson
    @Paul7Peterson Жыл бұрын

    Y para ese "ensureValueIsDefined()" podéis poner como devolución de tipo ": value is string" y un "return true;" para mejorar la inferencia de tipos en hilo.

  • @luka4695

    @luka4695

    Жыл бұрын

    en que mejoraria poner que devuelva un boolean en un void? que seria mejorar la inferencia?

  • @Paul7Peterson

    @Paul7Peterson

    Жыл бұрын

    @@luka4695 Por el narrowing. Al poner "value is string" como tipo de vuelta, cuando usas la función como condicional de bloque, dentro del bloque positivo el valor de la variable que has pasado como 'string | null | undefined' será de 'string'. Se puede hacer un "NotEmptyString" como tipo, pero eso es más avanzado.

  • @luka4695

    @luka4695

    Жыл бұрын

    @@Paul7Peterson gracias por la data

  • @barrenaedu
    @barrenaedu6 ай бұрын

    Otro comentario, yo soy del mundo java y veo mucho código con el uso excesivo del "this" cuando no es necesario salvo casos especiales (herencias, etc...); en el caso del UserEmail veo que en el constructor usan el "this" para llamar a los métodos ensure, si la cosa funciona como en java yo creo que es una mala costumbre usar el "this" ahí porque se empieza a propagar por todo el código, genera confusión para quien no sabe bien el uso del this, y se termina usando el this para todo como un prefijo que no tiene sentido y se pone "por las dudas" o "porque todo el mundo lo pone". Veo mucho esto, no se que opinan. Saludos.

  • @barrenaedu

    @barrenaedu

    6 ай бұрын

    Por ejemplo también veo lo estan usando en otros métodos de la clase, creo que ahí se puede mejorar la calidad del código, salvo desconozca algo del lenguaje que usan o haya algun patron/principio que me este pasando por alto; en cuyo caso super agradecido si me lo aclaran. Saludos

  • @felipemedinasalvatierra2094
    @felipemedinasalvatierra2094 Жыл бұрын

    Bueno si es un patron, pero VO igual DTO, es mejor usar estos objetos planos para la transferencia de datos y no usar modelos de dominios anemicos como la mayoria lo hace.

  • @hba6018
    @hba60183 ай бұрын

    Solucion elegante y sin verbosidad? Java Records.

  • @juanluispaz8282
    @juanluispaz8282 Жыл бұрын

    Uf, cuantas cosas están mal en este vídeo. Este patrón es también conocido como tipos opacos, muy común en programación funcional. El objetivo de este patrón es sacarle el máximo provecho al compilador; y al organizar el código con los tipos opacos consigues que las validaciones salgan de un montón de lugares (no solo en tu objeto user), quedando solo en el momento de colección de esos datos; que insisto es ante de crear un objeto user. Para ello creas un tipo para un dato concreto y lo usas a lo largo de tu aplicación, no solamente en User. Haciéndolo así permites que el compilador te ayude a detectar muchos problemas en muchos lugares diferentes. Aquí dicen que se crean una clase UserEmail, eso no existe, existe Email, da igual si se usa en User o no; y debe representar un email válido. En cuando a Id, debe ser una clase que valide que sea un uuid válido, y debe recibir como argumento genérico la entidad para la cual se aplica ese Id, de esa forma el compilador puede detectar el que intentes usar un id de una entidad en otra entidad. Si vas a crear una clase con un montón de clases internas solo para evitar llamar una función; y para ello tienes que armar tal lío teniendo que poner getters y setters en todo lados; por favor, no lo hagas, crea tus funciones de validación separadas de User sin más; el código final será más limpio que con estas clases que contienen un valor y que no aportan nada a tu objeto final más allá de complicarlo y de incrementar la presión sobre el recolector de basura. El valor del patrón radica en que los tipos opacos sean de uso extendido en la aplicación y no escondidos dentro una sola clase que nadie puede aprovechar. Estos tipos opacos normalmente los sueles ver con facilidad cuando haces el diseño de tu base de datos.

  • @gurugamer176

    @gurugamer176

    Жыл бұрын

    Eso mismo pense, ya con eso que explicaste se infringe solid especificamente la responsabilidad unica, deberia haber una clase externa que haga validaciones que sea abstracta a user, user es solo una entidad que representa atributos del usuario

  • @erickjhormanromero6905

    @erickjhormanromero6905

    Жыл бұрын

    Estos manes no saben nada

  • @tupapa7642

    @tupapa7642

    9 ай бұрын

    Lo único que entendí es que eres virgen JuanLuisPanza

  • @PedroSanchez-od7cc
    @PedroSanchez-od7cc Жыл бұрын

    Mucho boilerplate

  • @jorgegustavobanegas8491
    @jorgegustavobanegas84919 ай бұрын

    Estos videos son un crimen, sobre todo para lo que estan aprendiendo, porque empiezan a aprender las cosas mal.

  • @JoseQR
    @JoseQR Жыл бұрын

    Hola!, para las privadas los uso así: readonly #id: UserId;

Келесі