Quería felicitarte Martin, por tus videos. Lográs explicar en no más de 15 minutos, muchos conceptos que llevan quizás un semestre entero para comprender. No sólo los explicas con claridad, si no también que agregas ejemplos concretos! Felicitaciones por eso. Algo para aportar a tu video... Es que podrías continuar el ejemplo y explicar composite con ataques de un hero =) Saludos desde Argentina
Entendí perfectamente y pude relacionarlo con un codigo de pagos, dónde tienes un pago con una cantidad inicial y le aplicas decoradores para aplicar descuentos o aumentos al valor inicial, como cada pago decorado sigue siendo un pago entonces puedes hacer lo mismo que haces con todos los pagos como pagar, cancelar, posponer, etc.
Excelente, a veces el trabajo nos convierte en máquinas y nos aleja de la tan necesaria abstracción para resolver problemas. Videos como estos ayudan a entender los problemas desde otro enfoque y entender cómo funcionan las librerías que usamos. Buenos videos.
Me quedo muy claro con ese ejemplo el patrón decorador y un gran plus que lo explicaste con TS, y compilando usando deno. Excelente aporte!
4 роки тому
Buenísimo, y el final viendo cómo lo implementa la API de java fué lo mejor. Yo creo que conociendo los patrones de diseño populares y sabiendo cómo las librerías o APIs de los lenguajes lo implementan sería mucho más fácil aprender a usar un lenguaje con sus librerías de manera más apropiada. Siempre me he preguntado por qué las librerías o APIs no se enseñan a usar con patrones de diseño. En verdad creo que los patrones ayudan mucho a ser mejor programador. Yo soy fan de los patrones desde que los conocí y poco a poco intento implementarlos. Te agradezco el video.
Genial vídeo, si lo haces con los diferentes patrones sería magnifico. Aún que el tema de patrones es largo (hay muchos) ver su implementación después de la teoría, es simplemente magnifico. Un saludo.
Hermano has tardado mucho en subir esta serie. Mañana tengo examen de Diseño de Sistemas Software de la Universidad y me entra todo este tema. Wish me luck xD
hola, te sigo porque tus videos son interesantísimos, he aprendido mas como profesional, no son los típicos crud de UA-cam, me gustaría saber en que sistema empresarial podrías aplicar un diseño así.
Muy buen vídeo, me ha gustado mucho, me gustaría que siguieras tratando temas tan interesantes y también que hicieras algún vídeo de libros o recomendaciones para ser mejores programadores.
Muchas gracias por todos los vídeos que publica. Me encantaría ver un vídeo sobre inyección de dependencias y ejemplos en typescript(javascript) si fuera posible.
El problema que veo aqui es que tienes un orden al fin y al cabo. Independientemente al Enemy le pognas primero un casco y luego una armadura o al reves, primero una armadura y luego un casco. Me refiero, que si tienes el ejemplo de casco y luego armadura, para quitarle el casco o bien haces un getter para que el Decorator te devuelva el enemy interno o obligas a romper primero la armadura para luego romper el casco. Sería posible tener un ArrayList de decorators al enemy y que en cada ataque, se recorra dicho array calculando el daño? De esta forma si le rompes el casco, recorres el array de decorators y haces un pop(). Así en la siguiente iteración ese decorator ya no suma a la defensa.
Hola! una pregunta, como añadirías un orden a esos decoradores? por ejemplo en este caso son divisiones y por tanto el orden da igual, pero en el caso de que hubiera una suma/resta y luego una multiplicación o división, ahí sí que afectaría el orden, que se podría hacer en esa situación? un saludo y gracias por tus videos!!
En el ejemplo anterior que puse, se cumple exactamente la misma funcionalidad sin crear interfaces ni herencia y sin crear una clase para cada combinacion de capas. Al crear un enemigo base este recibe todo el daño de un ataque. Al añadir un objeto Helmet a la coleccion de decoradores del enemigo, el Helmet disminuye 10 puntos del ataque recibido, lo mismo con un enemigo que al añadir un objeto Armour a su coleccion que en el ejemplo que puse disminuye 25 puntos. Y por supuesto la coleccion puede tener añadidas tanto un objeto Helmet como un objeto Armour. Que el enemigo que tenga una configuracion tendria una resistencia de 35 puntos (10 + 25).
Muy buen vídeo, usando código para detallar el uso del patrón, y una duda que me surge es que tan recomendable es usar un patrón de diseño cuando ya hay mucho código avanzado, gracias por esta serie de patrones de diseño, que desde que los vi en la carrera me encantaron.
7:50 el método takeDamage() de la clase abstracta EnemyDecorator podría (debería) ser abstracto. Las mismas implementaciones concretas de EnemyDecorator van a implementar dicho método. Te ahorras el boilerplate de la implementación de un método que nunca será invocado.
Wow verdaderamente ahora queda mucho mas claro y no con tanta teoria que nos hacen creer los organismos publicos. Lo unico que me surgio fue una duda y es que diferencia habria entre usar esta arquitectura y usar listados/colecciones. Ejemplo: Clase Enemy: Dim Decorators as New Collection Public function ComputeDamage() For each decorator in Decorators vDamage = decorator.setDamage(vDamage) Next ComputeDamage = vDamage End Function Clase Helmet: Function SetDamage(pDamage) SetDamage = pDamage - 10 End Function Clase Armour: Function SetDamage(pDamage) SetDamage = pDamage - 25 End Function Y finalmente para decorar al Enemigo: BaseEnemy = new Enemy BaseEnemy.Decorators.Add new Helmet BaseEnemy.Decorators.Add new Armour
En este caso de uso tu método es totalmente válido 😀 La diferencia es que con Decorator no necesitas "modificar" el componentes que va a ser decorado. Me explico. En tu ejemplo funciona porque Enemy tiene conocimiento que va a recibir decoradores. Pero imaginate que quieres decorar clases que no son tuyas, que son de una librería o que son de sistema y por lo tanto no puedes acceder a su implementación para añadir esa lógica... Gracias por el comentario!
@@BettaTech Wow gracias por la increiblemente rapida respuesta. Y tambien por la aclaracion. Ahora soy mucho mas consciente de cuando usar uno y otro. :) Ahora vivo en un mundo de luz y color jejejeje mil gracias
Muy bueno el ejemplo final de aplicación sobre las clases de InputStream en la API de Java. ¿Tiene este patrón algo que ver con el paradigma AOP que implementa el framework Spring por ejemplo? Muchas gracias, utilísimo tu canal.
a mi me sale como si no existiera mi variable protected enemy en HelmetDecorator es como q no entendiera q extendi desde EnemyDecorator.. Es algo de mi editor VS o es algun plugin q me podria estar faltando? como tienes configurado tu VS para trabajar con TS? que me recomiendas?
Muy buen vídeo, como todos los de esta serie de patrones. Sólo me surge una duda en el ejemplo, entiendo que es un ejemplo pero... En estos ejemplos concretos en caso de que quiten el casco de un golpe...¿Cómo quitas de ese enemy ese decorador?
Cuando usas los dos puntos, : , por ejemplo takeDamage() : number, eso es solo porque es una interface o siempre que uses class y un método le puedes poner eso? , es como definir el tipo de valor que va a regresar, o con el que va a trabajar internamente? gracias por estos videos
Con este patrón, cómo sería para sacar un decorador? O sea si lo decoré 2, 3 o 4 veces, como se haría para sacarle el decorador 3, que sería solamente el casco por ejemplo?
Me gustaria saber que plugins usas para el VSCode. La verdad es que al ver esta explicación me dieron muchas ganas de empezar a jugar de nuevo con TypeScrypt. Gracias
Otra cosa mas. De los libros que recomendas, ¿Sabes si existen versiones en Español? y de ser el caso, ¿Los recomendarías o te parece mejor leerlos directamente en Ingles ?
Buen video :) tengo una pregunta, ya se que este video es para explicar el patron decorador. Pero en este caso no es mejor darle al Enemy un objeto que sea casco o armadura??
Gracias por el aporte ! una lástima lo de ts y deno D: (odio mucho, mucho, demasiado TS) pero lo más importante es el concepto y la sabiduría de la implementación lo cual hace que reste total importancia. Nuevamente gracias por todo
Un poco fuera del tema... me encanta el hecho de que ahora se deje mucho más fácil empezar a trabajar con ts directamente en deno, no creo que sea el killer pero si la alternativa que le hacia falta a node
estoy estudiandome el libro Head First Design Patterns de Eric Freeman Elisabeth Freeman , vi este video pero noto que no haces en python con visual code ninguno de los otros patrones EN CODIGO, se agradecería .
Buenos videos, pero se complican a mi parecer poniendo siempre como ejemplo juegos. Me parece más fácil poner ejemplos de ventas de una tienda o cosas más cotidianas y no tan rebuscadas...... a mi parecer.
Es un poco rebuscado, sobre todo al entender el resultado al montarlo todo por lo que dices de las capas de una cebolla (parecido a recursividad), no está mal el patrón. Pero tengo una duda, como cada clase decorada tiene dentro una clase "base", al tener varias capas, ¿no se instanciarían muchas clases intermedias que pudieran ocasionar problemas de memoria? Por ejemplo 10 capas serían 10 o 11 objetos en memoria para un solo enemigo... supongo que apenas se notaría, ni siquiera a escala, más allá del propio cálculo. ¿Qué dice la ciencia?
No entiendo muy bien la funcionalidad. Tú en tiempo de compilación dices que compute el daño el enemigo con armadura y casco no? ¿Pero y para hacerlo en tiempo de ejecución? Siguiendo el mismo ejemplo, a la hora de que un enemigo haga daño al jugador, no vas a saber fijo si el jugador tiene armadura, casco o lo que sea. Como usas el patrón entonces?
Ahora que me doy cuenta, que es explicas tus emplos de codigo como BDD. Osea piensas y codificas como quiere que tu codigo actue y luego codificas para que eso que escribiste funcione...
Os dejo el repositorio aquí por si os lo queréis bajar o cotillear!!
github.com/martincrb/decorator-design-pattern
Veo este video y me imagino Plants Vs Zombies. Excelente explicación! Felicidades!
Toda la serie de Patrones tendría que tener este enfoque! Y si mediante edición se pudiese ver la implementación vs su UML sería ya de 10!
Por eso siempre intento poner el UML con el "código" en la imagen en vez de simples "cajitas"... sólo que quizá es más difícil de leer jaja
Quería felicitarte Martin, por tus videos.
Lográs explicar en no más de 15 minutos, muchos conceptos que llevan quizás un semestre entero para comprender. No sólo los explicas con claridad, si no también que agregas ejemplos concretos! Felicitaciones por eso.
Algo para aportar a tu video... Es que podrías continuar el ejemplo y explicar composite con ataques de un hero =)
Saludos desde Argentina
Entendí perfectamente y pude relacionarlo con un codigo de pagos, dónde tienes un pago con una cantidad inicial y le aplicas decoradores para aplicar descuentos o aumentos al valor inicial, como cada pago decorado sigue siendo un pago entonces puedes hacer lo mismo que haces con todos los pagos como pagar, cancelar, posponer, etc.
Estos videos son buenísimos. Recomendadisimo a todos mis contactos.
Mil gracias!
Excelente, a veces el trabajo nos convierte en máquinas y nos aleja de la tan necesaria abstracción para resolver problemas. Videos como estos ayudan a entender los problemas desde otro enfoque y entender cómo funcionan las librerías que usamos. Buenos videos.
Mucho más claro así. Este patrón creo que necesitaba esta explicación extra. Gracias!
Super super útil, los demás patrones de la serie deberían tener un video así, mis dieses
Me quedo muy claro con ese ejemplo el patrón decorador y un gran plus que lo explicaste con TS, y compilando usando deno. Excelente aporte!
Buenísimo, y el final viendo cómo lo implementa la API de java fué lo mejor. Yo creo que conociendo los patrones de diseño populares y sabiendo cómo las librerías o APIs de los lenguajes lo implementan sería mucho más fácil aprender a usar un lenguaje con sus librerías de manera más apropiada. Siempre me he preguntado por qué las librerías o APIs no se enseñan a usar con patrones de diseño. En verdad creo que los patrones ayudan mucho a ser mejor programador. Yo soy fan de los patrones desde que los conocí y poco a poco intento implementarlos. Te agradezco el video.
Super ilustrativo! con una explicación así, más pausada y con código real se entiende mucho mejor. Gracias!
madre mia los patrones, como pude programar sin ellos
Lo máximo bro, viendo tus videos he entendió una cantidad de cosas que hasta ahora no lograba entender ...
Estoy iniciando con programación web y me encantan la forma en que explicas !
Muchas gracias, con código de ejemplo se entiende más que solo teoría
Excelente explicación y demostración muchas gracias por compartir tu conocimiento. Saludos...
Este enfoque práctico con codigo es increíble para este tipo de videos sobre patrones de diseño, gracias por todo tu trabajo Martín, sigue asi👏👏👏
Excelente video
deberías continuar con éste formato para los demás patrones de diseño
Gracias
Genial vídeo, si lo haces con los diferentes patrones sería magnifico. Aún que el tema de patrones es largo (hay muchos) ver su implementación después de la teoría, es simplemente magnifico.
Un saludo.
Me impresiona como maneja el concepto para en base al concepto saber que logia usar por eso es importante saber bien la teoria.
Hola, gracias por compartir tus conocimientos y ser tan buen divulgador.
Muchas gracias, excelente explicación... saludos. Tienes razón, con código real se entiende mejor.
Uffff, excelente explicación se nota el dominio de los conceptos de programación. Muchas felicidades por tan buen video.
En código real es mucho mejor, gracías!
Muy bueno! Lo entendi mucho mejor ahora :D
Gracias!! Lo importante es que quede claro 😊 Me alegra que te haya sido útil!
Hermano has tardado mucho en subir esta serie. Mañana tengo examen de Diseño de Sistemas Software de la Universidad y me entra todo este tema. Wish me luck xD
Muy bien explicado, un patrón muy bonito. Explicado mejor incluso que el libro HeadFirst que tienes ahí atrás :)
hola, te sigo porque tus videos son interesantísimos, he aprendido mas como profesional, no son los típicos crud de UA-cam, me gustaría saber en que sistema empresarial podrías aplicar un diseño así.
Excelente ejemplo de patrón, muy claro,crack 👍haces videos muy buenos
Muy buen vídeo, me ha gustado mucho, me gustaría que siguieras tratando temas tan interesantes y también que hicieras algún vídeo de libros o recomendaciones para ser mejores programadores.
Muchas gracias por todos los vídeos que publica. Me encantaría ver un vídeo sobre inyección de dependencias y ejemplos en typescript(javascript) si fuera posible.
El otro video se quedo muy teorico. Aqui se ve todo muy claro! :D
Que brutal esa informacion, no puedo decir mas. 10/10
Gracias por comentar
Excelente explicación
Visto en 11/06/2020
Todo muy claro. Muchas gracias.
Excelente trabajo! Admirable el gusto por compartir conocimiento.
Gracias!
Muy buena explicación. Gracias!
muchas gracias por el video, muy bien explicado, un saludo!!
Excelente video con una explicación súper clara. ¡Muchas gracias por tan buen video!
Gracias a ti por verme! :D
Una genialidad 🙋♀️
Super explicado, creo que seria bueno que de la misma forma explicaras los anteriores.
LIKE PARA QUE LO VEA
Podrías hacer uno haciendo un pequeño proyecto y explicar los principios solid ampliamente por favor!
Que buen video amigo , gracias por compartir tu conocimiento
Más aplicaciones de patrones con código por favor, muy buenos tus videos!
Muchas gracias por estos buenos videos BettaTech! Sigue así con el buen contenido se te apoya siempre desde Nicaragua.
Gracias Rekefa! Saludos a todos desde aquí!! :D
Simplemente gracias !!
El problema que veo aqui es que tienes un orden al fin y al cabo. Independientemente al Enemy le pognas primero un casco y luego una armadura o al reves, primero una armadura y luego un casco. Me refiero, que si tienes el ejemplo de casco y luego armadura, para quitarle el casco o bien haces un getter para que el Decorator te devuelva el enemy interno o obligas a romper primero la armadura para luego romper el casco.
Sería posible tener un ArrayList de decorators al enemy y que en cada ataque, se recorra dicho array calculando el daño? De esta forma si le rompes el casco, recorres el array de decorators y haces un pop(). Así en la siguiente iteración ese decorator ya no suma a la defensa.
Hola! una pregunta, como añadirías un orden a esos decoradores? por ejemplo en este caso son divisiones y por tanto el orden da igual, pero en el caso de que hubiera una suma/resta y luego una multiplicación o división, ahí sí que afectaría el orden, que se podría hacer en esa situación? un saludo y gracias por tus videos!!
¡Me ha encantado el vídeo! Tu voz se parece un montón a la de MoureDev 🤯😂
En el ejemplo anterior que puse, se cumple exactamente la misma funcionalidad sin crear interfaces ni herencia y sin crear una clase para cada combinacion de capas. Al crear un enemigo base este recibe todo el daño de un ataque. Al añadir un objeto Helmet a la coleccion de decoradores del enemigo, el Helmet disminuye 10 puntos del ataque recibido, lo mismo con un enemigo que al añadir un objeto Armour a su coleccion que en el ejemplo que puse disminuye 25 puntos. Y por supuesto la coleccion puede tener añadidas tanto un objeto Helmet como un objeto Armour. Que el enemigo que tenga una configuracion tendria una resistencia de 35 puntos (10 + 25).
Muy buena explicación!
Muy buen vídeo, usando código para detallar el uso del patrón, y una duda que me surge es que tan recomendable es usar un patrón de diseño cuando ya hay mucho código avanzado, gracias por esta serie de patrones de diseño, que desde que los vi en la carrera me encantaron.
Excelente ejemplo!
7:50 el método takeDamage() de la clase abstracta EnemyDecorator podría (debería) ser abstracto. Las mismas implementaciones concretas de EnemyDecorator van a implementar dicho método. Te ahorras el boilerplate de la implementación de un método que nunca será invocado.
Totalmente! Se me pasó por alto :)
Eres un genio! Excelente contenido!
Muchas gracias! 😄
Wow verdaderamente ahora queda mucho mas claro y no con tanta teoria que nos hacen creer los organismos publicos.
Lo unico que me surgio fue una duda y es que diferencia habria entre usar esta arquitectura y usar listados/colecciones. Ejemplo:
Clase Enemy:
Dim Decorators as New Collection
Public function ComputeDamage()
For each decorator in Decorators
vDamage = decorator.setDamage(vDamage)
Next
ComputeDamage = vDamage
End Function
Clase Helmet:
Function SetDamage(pDamage)
SetDamage = pDamage - 10
End Function
Clase Armour:
Function SetDamage(pDamage)
SetDamage = pDamage - 25
End Function
Y finalmente para decorar al Enemigo:
BaseEnemy = new Enemy
BaseEnemy.Decorators.Add new Helmet
BaseEnemy.Decorators.Add new Armour
En este caso de uso tu método es totalmente válido 😀 La diferencia es que con Decorator no necesitas "modificar" el componentes que va a ser decorado. Me explico. En tu ejemplo funciona porque Enemy tiene conocimiento que va a recibir decoradores. Pero imaginate que quieres decorar clases que no son tuyas, que son de una librería o que son de sistema y por lo tanto no puedes acceder a su implementación para añadir esa lógica...
Gracias por el comentario!
@@BettaTech Wow gracias por la increiblemente rapida respuesta. Y tambien por la aclaracion. Ahora soy mucho mas consciente de cuando usar uno y otro. :) Ahora vivo en un mundo de luz y color jejejeje mil gracias
Muchas gracias amigo !
Muy bueno el ejemplo final de aplicación sobre las clases de InputStream en la API de Java. ¿Tiene este patrón algo que ver con el paradigma AOP que implementa el framework Spring por ejemplo? Muchas gracias, utilísimo tu canal.
capo se entedio perfecto, gracias
Bárbaro, buenisimo
a mi me sale como si no existiera mi variable protected enemy en HelmetDecorator es como q no entendiera q extendi desde EnemyDecorator.. Es algo de mi editor VS o es algun plugin q me podria estar faltando? como tienes configurado tu VS para trabajar con TS? que me recomiendas?
Hola amigo , un saludo! ¿Que tal una serie sobre arquitectura de software ? estaría buenísimo
Qué libro recomiendas para aprender patrones de diseño ?
Muchas gracias.
Gracias muy bueno!
Muy buen vídeo, como todos los de esta serie de patrones.
Sólo me surge una duda en el ejemplo, entiendo que es un ejemplo pero... En estos ejemplos concretos en caso de que quiten el casco de un golpe...¿Cómo quitas de ese enemy ese decorador?
Ahora si entendí!!! ☺
No sabia que Caradechiste haga videos de programación v:
Qué tema de vscode tenías en ese momento?
Cuando usas los dos puntos, : , por ejemplo takeDamage() : number, eso es solo porque es una interface o siempre que uses class y un método le puedes poner eso? , es como definir el tipo de valor que va a regresar, o con el que va a trabajar internamente? gracias por estos videos
Indica el tipo del valor de retorno de la funcion 😊
@@BettaTech Ah, gracias buen hombre.
Que tema es el que tienes en el visual studio code.?
Con este patrón, cómo sería para sacar un decorador? O sea si lo decoré 2, 3 o 4 veces, como se haría para sacarle el decorador 3, que sería solamente el casco por ejemplo?
¿Qué tema usas en vs code?
Que theme usas para vs code, esta chevere !
BettaTerch, haga un video sobre este patrón pero con Unity y C#.
Este patrón se entiende aun mucho mas en Python.
Me gustaria saber que plugins usas para el VSCode.
La verdad es que al ver esta explicación me dieron muchas ganas de empezar a jugar de nuevo con TypeScrypt.
Gracias
Otra cosa mas. De los libros que recomendas, ¿Sabes si existen versiones en Español? y de ser el caso, ¿Los recomendarías o te parece mejor leerlos directamente en Ingles ?
Buen video :)
tengo una pregunta,
ya se que este video es para explicar el patron decorador.
Pero en este caso no es mejor darle al Enemy un objeto que sea casco o armadura??
Muchas gracias!!
Gracias por comentar!!!!
excelente gracias!
Si tengo un objeto con varios decoradores, como puedo quitar un decorador del medio?
gracias.
Tienes algun video explicando MVC?
Gracias.
¿Es posible comprobar si ya existe un decorador aplicado? ¿es posible ordenar el orden de las decoraciones aplicadas?
Diay si...... no hay una explosión de clases de enemigos pero hay una explosión de clases decoradoras 🤣🤣🤣
Y cómo harías si quieres quitar decoradores a un objeto ya instanciado?
Excelente explicación y ejemplo, como diría Shrek, los decoradores son como las cebollas, tienen capas
Buen video
Gracias por el aporte ! una lástima lo de ts y deno D: (odio mucho, mucho, demasiado TS) pero lo más importante es el concepto y la sabiduría de la implementación lo cual hace que reste total importancia. Nuevamente gracias por todo
Odiar lenguajes es de simps
Un poco fuera del tema... me encanta el hecho de que ahora se deje mucho más fácil empezar a trabajar con ts directamente en deno, no creo que sea el killer pero si la alternativa que le hacia falta a node
Y el composite para cuando? :-)
y para quitarle el casco?
estoy estudiandome el libro Head First Design Patterns de Eric Freeman
Elisabeth Freeman , vi este video pero noto que no haces en python con visual code ninguno de los otros patrones EN CODIGO, se agradecería .
Buenos videos, pero se complican a mi parecer poniendo siempre como ejemplo juegos. Me parece más fácil poner ejemplos de ventas de una tienda o cosas más cotidianas y no tan rebuscadas...... a mi parecer.
Es un poco rebuscado, sobre todo al entender el resultado al montarlo todo por lo que dices de las capas de una cebolla (parecido a recursividad), no está mal el patrón.
Pero tengo una duda, como cada clase decorada tiene dentro una clase "base", al tener varias capas, ¿no se instanciarían muchas clases intermedias que pudieran ocasionar problemas de memoria? Por ejemplo 10 capas serían 10 o 11 objetos en memoria para un solo enemigo... supongo que apenas se notaría, ni siquiera a escala, más allá del propio cálculo. ¿Qué dice la ciencia?
No entiendo muy bien la funcionalidad. Tú en tiempo de compilación dices que compute el daño el enemigo con armadura y casco no? ¿Pero y para hacerlo en tiempo de ejecución?
Siguiendo el mismo ejemplo, a la hora de que un enemigo haga daño al jugador, no vas a saber fijo si el jugador tiene armadura, casco o lo que sea. Como usas el patrón entonces?
Ahora que me doy cuenta, que es explicas tus emplos de codigo como BDD. Osea piensas y codificas como quiere que tu codigo actue y luego codificas para que eso que escribiste funcione...
claro sin escribir test propiamente.
Cómo se llama el estilo de tu visual studio? xdxd
Pues o es Horizon o es Dracula.
Yo uso github theme, es bastante amigable
Primer comentario
... Mamá, no te fallé