Mejora tu Código Eliminando IFs con el Patrón Strategy

Поделиться
HTML-код
  • Опубликовано: 17 окт 2024

Комментарии • 66

  • @evazquez70
    @evazquez70 20 дней назад +30

    El ejemplo de como implementar la interface es excelente, sin embargo no se elimina la necesidad de usar alguna sentencia de decision para saber que estrategia vamos a pasar como parametro para que el servicio use la clase correcta con el descuento por tipo de cliente.

    • @nicolasdemaio955
      @nicolasdemaio955 19 дней назад

      Un ejemplo de implementación para eliminar la necesidad de la sentencia seria que cada tipo de descuento sepa respondernos a que tipo de cliente aplica.
      Ejemplo:
      IDiscountStrategy tendria un metodo #canHandle que recibe como argumento un tipo de cliente.
      func canHandle(string aCustomerType): boolean
      Y cada clase concreta que lo implementa nos responderia verdadero en caso de que aplique al tipo de cliente recibido por parametro.
      ejemplo: class PremiumDiscountStrategy implements IDiscountStrategy {
      func canHandle(string aCustomerType): boolean {
      return aCustomerType == "Premium"
      }
      }
      Y dentro de la clase DiscountService (tomando como ejemplo el video), tendriamos una lista de estrategias de descuentos donde evaluamos cual puede aplicar para un CustomerType dado, y luego invocar el metodo #GetDiscount.

    • @kmaradaepna
      @kmaradaepna 16 дней назад

      Estoy de acuerdo :)
      Para ser completo debería añadir un método que recibiese el tipo de cliente via string y devolviese su descuento usando el patrón strategy. Si no, nos estamos haciendo un poco de trampas al solitario.
      Dicho esto, la explicación muy bien!!!!!

    • @benjamin5002
      @benjamin5002 5 дней назад

      Eso mismo estaba pensando, la decisión estaría cambiada al selector o combobox donde indique el tipo de cliente, o alguna variable donde se indique cuál estrategia a seguir. Pero sin duda simplifica y ayuda a mantener el código de implementación. muchas gracias.

  • @ceisistemas2200
    @ceisistemas2200 18 дней назад

    Hola ante todo, el mundo de la programacion es fascinante, usar If anidados es complicado funciona si, pero no es muy recomendable y mantenible, tu estrategia es buena igual pero crear clases por cada caso, igual complica, para usar casos donde hay opciones múltiples y complejas se puede usar Switch y case en c#, on case, case en otros lenguajes yo uso para validar por ejemplo varios campos con diferentes valores en una sola clase y un solo método, es mucho más fácil y muy estructurado, de todas formas, la lógica es como la frase todos los caminos van roma, unos más largos otros, no, sin embargo saber otros métodos es importante, felicitaciones y gracias por compartir conocimientos.

  • @mariojoverlorenzo7282
    @mariojoverlorenzo7282 10 дней назад +1

    Puede que no haya entendido por eso pregunto, en tu caso no es lo mismo? Es decir tu llamas a un servicio u otro dependiendo del tipo de cliente, entonces al final tendras "if (clienteVip) {vipStrategy}else if ....." o no he entendido bien

    • @DaniCCardenas
      @DaniCCardenas  9 дней назад

      Si, tienes razón. El ejemplo esta muy simplificado buscando que se entienda el patrón, que básicamente consiste en poder tener distintas implementaciones (estrategias) para un problema. En este ejemplo concreto no eliminarías if, pero lo importante es comprender los patrones para así detectar cuando pueden ser útiles y usarlos en ese momento.

  • @reylova
    @reylova 20 дней назад

    Me encanto. Me suscribí a tu canal. Bien explicado y mostrado. Excelente. Gracias 👍

    • @DaniCCardenas
      @DaniCCardenas  20 дней назад

      Muchas gracias por el comentario, me alegra mucho que te haya servido

  • @jorgeandres4234
    @jorgeandres4234 13 дней назад

    Es interesante el planteamiento desde el punto de vista de mejora, esto hace el código mas sostenible. Un detalle a tomar en cuenta es que si el tipo de cliente es dinámico (por ejemplo si viene de un formulario) ¿Cómo se maneja la validación para que toma la estrategia del descuento si el if else?

    • @xavierr4508
      @xavierr4508 12 дней назад

      No se puede, los condicionales solamente se movieron de lugar, pero siempre los vas a necesitar.

  • @jesusnoguera8725
    @jesusnoguera8725 21 день назад +4

    Hola, excelente video, me he suscrito, estaré atento a los futuros videos sobre patrones de diseño, es un tema que me genera mucho interés
    Una pregunta en un código un poco más real para obtener el descuento en función del rol (Regular, VIP, Premium) de igual forma se tendrían que tener un if o switch por cada caso para saber que clase que implemente la interfaz de IDiscountStrategy instanciar?
    Gracias!

    • @rockVANiaN
      @rockVANiaN 21 день назад +1

      Me hice la misma pregunta y creo que realmente no desaparecen los ifs, sino que se mueven a otra parte del proyecto, porque en algún momento tienes que evaluar que estrategia vas implementar. Esto puede confundir un poco, pero también es verdad que es mucho más fácil mantener y entender un código con este patrón.
      También quizá si haya algún ejemplo en donde realmente si desaparezcan los ifs. Estaría bien si pudieran compartir algún ejemplo que abarque el panorama global.
      Buen video y gracias por compartir.

    • @DaniCCardenas
      @DaniCCardenas  21 день назад +2

      Si, los if y los switch...case no son malos. Puedes y debes usarlos cuando sea necesario. La idea es no abusar y hacer programación orientada al if. Este ejemplo es tonto, pero he visto decenas de if anidados que hacen inmantenible el código y súper complicado de probar. Aquí si tienes cada estrategia por separado, es más fácil probarlas y cambiar algo si es necesario. Y añadir nuevos escenarios si lo necesitas. Gracias por los comentarios!!!

    • @sota9961
      @sota9961 20 дней назад +1

      La idea del patrón no es exactamente hacer desaparecer los ifs, los cuales son necesarios para el ejemplo. Lo que hace es no tener la lógica dentro de estos ifs. Imagina que el descuento lo aplicas en 10 partes de tu código. Ahora tienes que modificar el descuento que le haces a un VIP. En vez de modificarlo en 10 sitios solo debes hacerlo en 1. Más bien es encapsulamiento de código, como harías con una función. La única ventaja frente a usar funciones realmente es el polimorfismo que aporta, ya que la clase que hace el descuento no tiene por qué ser consciente de qué tipo de descuento se va a aplicar (es decir, esa clase no la tendrías que modificar nunca más)

    • @JoSe086
      @JoSe086 20 дней назад +4

      No es necesario usar if’s ni switches, puedes crearte un diccionario en el que la clave sea el tipo de descuento y el valor sea la instancia del descuento que quieres usar

  • @adanpalma4026
    @adanpalma4026 20 дней назад +9

    Es increíble como nos fanatizamos con las cosas.
    Entonces tengo que definir en clases por cada tipo de cliente sólo para manejar el discount y luego descubrir en cada clase cómo se aplica cada discount porque a primera vista se verá más bonito será más legible pero la lógica de qué hace cada discount en cada clase yo no la sé tendría que ir a cada clase y estudiarlo entonces por algo tan básico como una estructura de control de un par de Ive en donde en un solo punto puedo modificar todo y verlo y lo puedo ver de una vez lo cambio por una dispersión de clases brillante

    • @LV-cn9bx
      @LV-cn9bx 20 дней назад

      Totalmente de acuerdo

    • @nicolasdemaio955
      @nicolasdemaio955 19 дней назад +1

      Clean code y principios SOLID, los conoces? SRP y OCP.
      Si negocio o stakeholders deciden agregar 4 tipos de clientes más, agregarias 4 ifs mas?
      Y si la logica de uno de los descuentos no es solo hacer una simple cuenta matematica, sino calcular en base a la cotizacion de X moneda?
      Entiendo que sos un programador junior.

    • @beetfeater
      @beetfeater 19 дней назад +2

      A ver panoli, esto es un simple ejemplo, cuando en ese if tengas que añadir 100 lineas de codigo por cada sentencia esto tendrá mucho mas sentido, solo tienes que pensar un poquito.

    • @xavierr4508
      @xavierr4508 12 дней назад

      El ejemplo tiene problemas más profundos, pero dentro de lo rescatable, debes estudiar sobre patrones e ingeniería de software para que entiendas la razón de ser de este y los demás patrones.
      Sin embargo, si eres feliz programando en la superficie, así quédate, no aspires a ser mejor.

    • @xavierr4508
      @xavierr4508 12 дней назад +1

      @@nicolasdemaio955 No creo que los conozca, por eso hizo el comentario =)

  • @jose-sebastian-garcia
    @jose-sebastian-garcia 9 дней назад

    Una vez tuve que codear una calculadora de axie infinity, si hubiera sabido el patron strategy, se me habria facilitado taanntoo el laburo... terrible acople tuve por no usarlo

  • @williansuarez3988
    @williansuarez3988 21 день назад +1

    Interesantísimo, buen video, aunque no entendí todo, ¿se puede implementar en otros lenguajes?, todavía me falta mucho por aprender

    • @DaniCCardenas
      @DaniCCardenas  21 день назад

      Hola, los patrones son algo agnóstico al lenguaje y si sabes cómo funcionan luego puedes aplicarlos con cualquier lenguaje.

    • @williansuarez3988
      @williansuarez3988 20 дней назад

      @@DaniCCardenas ¡Gracias!

  • @kronosaqp
    @kronosaqp 17 дней назад

    Excelente video y muy interesante, sim embargo creo que si bien hace mas legible el código, es mucho complicado y requiere mas tiempo para implemetarlo que un simple if, y esto puede llevar a cometer mas errores de sintaxis. Cuando son pocos casos creo que basta con un else if, si son varios con un case bastará, ahora si son muchos y tienen una logica complicada por cada caso, el Patrón Strategy es la solución. Gracias por el video, muy bueno.

    • @DaniCCardenas
      @DaniCCardenas  17 дней назад

      Efectivamente, en este caso el ejemplo era sencillo para poder explicar de forma sencilla el patrón. En proyectos grandes y funcionalidades grandes, mejor separar en clases que tener "código espagueti"

  • @diegom.3782
    @diegom.3782 17 дней назад

    Hola la estrategia que pusiste es para un cliente vip pero como sabes que es vip? (la explicacion muy buena, me suscribi para ver el resto, muchas gracias)

    • @DaniCCardenas
      @DaniCCardenas  17 дней назад +1

      Hola, pues tienes que tener tu lógica previa para eso. Tal vez venga de la base de datos por que así ha sido tipificado, o tal vez tengas cálculos previos y se convierte en VIP cuando hace mas de xxxx en gasto. En este caso era un simple ejemplo para mostrar strategy

  • @juandavidjulio
    @juandavidjulio 21 день назад

    Genial. Que buena estrategia

  • @industriasroy7343
    @industriasroy7343 19 дней назад

    Excelente video, como sugerencia podrias poner el tamaño de letra mas grande. Algunos no tenemos muy buena vista y en el celular no lo pude ver.

  • @fabiomijango
    @fabiomijango 21 день назад

    Buen video

  • @erwincorzo9009
    @erwincorzo9009 17 дней назад +1

    Para las personas que siguen pensando en los if, una alternativa puede ser crear un Map y basado en el parametro de entrada obtener la implemnentacion que desean.
    OJO: Los mapas son mas lento para recorrer uno a uno que una lista, pero si sabes de antemanos la llave de tu mapa puede obtener tu implementacion.

    • @DaniCCardenas
      @DaniCCardenas  17 дней назад

      Si son una buena opción para este caso de ejemplo. Aunque el objetivo del video era explicar Strategy. Gracias por tu comentario!

  • @JackCespedes
    @JackCespedes 16 дней назад +2

    En ningún momento reemplazaste los if... lo que hiciste es aumentar código... creo que hubieses planteado un mejor ejemplo...

  • @loopme4659
    @loopme4659 21 день назад +1

    Súper pero entonces el if va del lado donde llamas la interfaz asignándole la estrategia que implementas

    • @DaniCCardenas
      @DaniCCardenas  21 день назад

      Un if, un switch...case, lo que necesites. Los if como tal no son malos y puedes/debes usarlos cuando lo necesites. La idea aquí es no abusar de ellos y hacer un código más mantenible y testeable

  • @otrejo2606
    @otrejo2606 8 дней назад

    Pero igual vas a tener que hacer el if, lo.mas sensato es manejarlo por bd y entities para al retornar el cliente obtener el tipo de cliente y su configuración y así aplicar el descuento cuando aplique solo que la bd debe representar si el tipo de cliente aplica descuento y el valor de descuento vigente... Yo lo manejaría así

  • @alfonsomaparicio6130
    @alfonsomaparicio6130 15 дней назад

    Para este ejemplo de descuentes no se ve la potencia. Se suele usar para comportamientos, sin cambiar el codigo y hacerlo modular. En un determinado momento necesitas cambiar la estrategia de aplicar descuento , y esos ifs te los quitaras si diseñas bien el uso de ellos. Ejemplo, una clase base que aplica descuentos y que las derivadas aplican ya en un metodo el patron estrategy

    • @json24866
      @json24866 12 дней назад

      No necesariamente eliminas los if... imaginate un caso de un metodo login() donde el usuario ingresa su usuario y contraseña... y en ese momento tu usuario queda configurado.. y ahora que pasa luego al hacer una compra con descuento? que necesitas un if para determinar el tipo de cliente y luego crear un strategy

  • @lorenzogrv
    @lorenzogrv 15 дней назад +1

    El problema que veo aquí es sobre-simplificar el caso de aplicación del patrón. A mi modo de ver lo que de verdad importa no es el patrón en sí, sino el problema que resuelve. Simplificar tanto el problema diluye la ventaja que aporta aplicar el patrón y por tanto dificulta entenderlo. Dicho de otro modo y con todos mis respetos, creo que escogiste un mal ejemplo.

  • @xavierr4508
    @xavierr4508 12 дней назад

    1. ¿Porqué están peleados con los diagramas? ¿Porqué todo lo quieren hacer sobre el código? Existen herramientas gratis para dibujar sobre la pantalla.
    2. Más importante, la premisa del título del video no se cumple ya que olvidaste mencionar que solamente moviste el condicional de lugar, nunca se fue (y los condicionales nunca se van a ir).
    3. Quizás fue porque el ejemplo era sobre otra cosa, pero es una terrible idea tener a los porcentajes de descuento como magic numbers; eso nunca va a escalar.

  • @manuelc65
    @manuelc65 20 дней назад +1

    No esto de acuerdo no me parece amigable es más enredado porque veo las clases separadas del código no se si vi más líneas de código con su método, que te gusta. No sé si porque ya estoy acostumbrado, pero a mí NO me parece mejor ni más amigable y si es un código grande serían más clases con distintos nombres imagina que tienes 100 if serian 100 clases con distintos nombres así que no creo que sea mejor y disculpa si estoy equivocado, pero eso fue lo que entendí

    • @DaniCCardenas
      @DaniCCardenas  20 дней назад +5

      El ejemplo que uso tiene solo 3 if y se ve sencillo de mantener. Pero imagina una clase, con 5K líneas de código, y 14 if anidados, cada if con varios and y or, y luego dentro del if, varios if mas, con varios niveles de anidación. Yo lo he visto, no me lo estoy inventando. Ahora, que te digan que tienes que tocar el comportamiento de algunas de esas condiciones y además, añadir un par de comportamientos mas. Cambia eso y pruébalo. Obviamente, ya lo he dicho en varios comentarios, no digo que no se tenga que usar IF...else o Switch...case, es mas, debes usarlos que para eso están ahí. Los patrones has de decidir si te compensa usarlos o no en cada momento, no existen las balas de plata, pero es importante conocerlos para ser mejor programador y saber cuando compensa y cuando no. En un código como el del ejemplo en un proyecto real, yo lo haría a base de if posiblemente, pero es valido para explicar el concepto de la forma mas sencilla y entendible posible. Por supuesto, cada uno es libre de programar como considere.

    • @oarangov
      @oarangov 17 дней назад

      Siempre debes buscar el mayor desacoplamiento posible. No sólo por testabilidad, sino por mantenibilidad. Tener todo en un archivo, complica ambas cosas. Al principio puede parecer que tener tantos archivos es engorroso, pero hace la vida más fácil.

    •  4 дня назад

      @@DaniCCardenas entonces lo que entiendo es seguir manteniendo los if o wl switch ya sea 2 opciones o N, lo que va dentro del if puede ser metodos que devuelvan el true o false y cumpliendo la condición llamar el strategy que se desea
      if(isVip()){
      strategyVip();
      }else{
      strategyRegular();
      }
      esto para que se vea mas legible el codigo, porque veo en el ejemplo que pones que tu le indicas el strategy que desea ocupar.

  • @javea6572
    @javea6572 20 дней назад +7

    Problemas de calidad de código que veo a esta solución:
    1º) Generas clases anémicas cuya abstracción se basa en solo realizar 1 acción, el propósito del problema es eliminar el if y el switch.
    2º) Primitive obsesión: usamos valores string, hay que tiparlos en un enumerado, evitaremos luego excepciones y mala práxis (evitad hardcodeos).
    3º) Sobre ingeniería: La creación de clases para cada tipo de descuento introduce complejidad innecesaria, especialmente cuando la lógica de descuento es trivial. Mantener un gran número de clases que hacen lo mismo puede ser innecesariamente costoso en términos de mantenimiento.
    4º) Duplicación de lógica: Aunque cada clase representa un tipo de descuento diferente, la implementación es prácticamente idéntica, lo que puede resultar en duplicación de código y futuras dificultades para realizar modificaciones o extensiones.
    5º) Errores tipográficos: Es fácil cometer errores tipográficos al utilizar cadenas de texto para definir tipos. Por ejemplo, si accidentalmente se escribe "Vip" en lugar de "VIP", no se aplicará ningún descuento y será difícil rastrear el origen del error.
    6º) Falta de claridad: string no comunica claramente las opciones válidas para los tipos de clientes, y cualquier valor de cadena es válido en el código, lo que lo hace más difícil de mantener.
    7º) Duplicación de lógica: Si el mismo customerType se usa en otras partes del sistema, es probable que la validación y el manejo de este string se dupliquen.
    8º) Dificultad para extender: Si en el futuro se agregan más tipos de cliente o más lógicas para seleccionar estrategias, el DiscountStrategy se volverá más complejo, dificultando el mantenimiento y extensibilidad.
    9º) Mayor complejidad: Cada vez que se agregue una nueva estrategia o tipo de cliente, se tendrá que modificar esta clase, aumentando la complejidad y violando el principio abierto/cerrado (OCP), que establece que las clases deben estar abiertas a la extensión, pero cerradas a la modificación.
    10) Baja extensibilidad: Si en el futuro quieres agregar nuevos tipos de clientes, tendrás que seguir añadiendo clases y modificando DiscountStrategy . Este proceso es tedioso y rompe el principio de abierto/cerrado.
    En resumen.. ASÍ es como yo enseño a mi equipo y compañeros como líder técnico....
    // Enumerado para representar los tipos de cliente
    public enum CustomerType
    {
    Regular,
    Premium,
    VIP
    }
    // Clase DiscountService con el diccionario de descuentos
    public class DiscountService
    {
    // Diccionario que mapea el tipo de cliente con el factor de descuento
    private readonly Dictionary discountTable = new Dictionary
    {
    { CustomerType.Regular, 0.05 }, // 5% descuento
    { CustomerType.Premium, 0.1 }, // 10% descuento
    { CustomerType.VIP, 0.2 } // 20% descuento
    };
    // Método para calcular el descuento basado en el tipo de cliente
    public double GetDiscount(CustomerType customerType, double amount)
    {
    // Si el tipo de cliente no existe en el diccionario, el descuento será 0
    double discountFactor = discountTable.GetValueOrDefault(customerType, 0);
    return amount * discountFactor;
    }
    }
    Con esto....
    * Menor complejidad: El código es mucho más simple, sin necesidad de múltiples clases o estructuras condicionales. Esto mejora la mantenibilidad y reduce la complejidad ciclomática.
    * Extensibilidad: Añadir nuevos tipos de clientes es tan sencillo como agregar una nueva entrada en el diccionario.
    * Responsabilidad de experto de información (GRASP): Colocamos la lógica de cálculo en el servicio donde tiene sentido que ocurra, sin crear estructuras innecesarias, manteniendo una alta cohesión.
    He aplicado concepto de calidad de código, metodología GRASP y aplicado el patrón Strategy QUE ES UN PATRÓN de comportamiento aplicable como lo he puesto.. generar clases, abogas más a un patrón de estructura ....

    • @DaniCCardenas
      @DaniCCardenas  20 дней назад +3

      Amigo... que es un ejemplo para explicar Strategy...

    • @javea6572
      @javea6572 20 дней назад +1

      @@DaniCCardenas ya, pero el ejemplo si lo haces así, entonces, muchos lo harán así con esos problemas que indico y no resolvemos mucho , porque tras +25 años de experiencia y en 2024, No he encontrado un proyecto donde se aplique los famosos "patrones de diseño" y todo se basa porque NO ven la visibilidad de su uso, no saben lo que es la abstracción , la interface (cosa que explicas bien, pero MUCHOS no lo entienden) y porque se tiene que aplicar... hay que luchar contra el "síndrome de Dunning Kruger" cuando se hace un ejemplo así 🤗🤗

    • @DaniCCardenas
      @DaniCCardenas  20 дней назад +1

      Que a ver, no me malinterpretes, que las "magic string" son el mal estoy de acuerdo, es mas, que la implementación que has puesto tu para ESE código es mejor también estoy de acuerdo. En eso estamos de acuerdo. Pero he buscado un ejemplo sencillo para explicar el concepto. Es el que se me ha ocurrido en el momento de preparar el video, no hay mas.
      Ahora bien, lo que si podríamos debatir es el motivo por el que en consultoría no se aplican patrones y buenas prácticas (en general) :)
      Por cierto, gracias por participar y aportar.

    • @MaikeLDave
      @MaikeLDave 18 дней назад

      @@javea6572mis dies, podrías recomendar algun curso o libro?

    • @sirone2002
      @sirone2002 18 дней назад +2

      @@javea6572 concuerdo contigo respecto a que es dificil encontrar información sobre la verdadera utilidad de los patrones de diseño, como en este video que se me hace demasiado código para un simple descuento y quizás por eso no le veo utilidad alguna, no he encontrado en ningún proyecto una necesidad tan relevante que me lleve a investigar más sobre Strategy, pero también entiendo que la temática del descuento en este video es meramente como ejemplo y ese es el problema, al ser algo tan sencillo no se le ve el posible potencial que quizás tenga este patrón de diseño.

  • @hba6018
    @hba6018 18 дней назад

    es C#?? dislike y adios!