El patrón estrategia o strategy pattern

Definición

El patrón estrategia define un conjunto de algoritmos, encapsula cada uno de ellos y los hace intercambiables. Estrategia permite que el algoritmo varie independientemente de los clientes que lo utilicen.

Modelo UML

Hey, Alberto stops doing that!!!

Ok chicos ya vimos todo lo que tienen que saber de memoria para impresionar a sus amigos y  jefes. 

Ahora vamos a tratar de aterrizar todos estos conceptos en el mundo real de forma que puedan quedar en nuestras cabezas y más importante aún que podamos utilizarlos sabiendo claramente cómo identificar el problema que resuelve este patrón de diseño.

Pensemos un poco en cada punto de la definición 

El patrón estrategia define un conjunto de algoritmos…

Tenemos varios algoritmos que queremos utilizar: A, B, C etc.

…encapsula cada uno de ellos y los hace intercambiables…

OK entonces estos algoritmos (A, B, C) los podemos utilizar según necesitemos, algunas veces por ejemplo usaremos (B,  C) y otras solo (A) .

…permite que el algoritmo varie independientemente de los clientes que lo utilicen.

Digamos que tenemos una lista de nombres  “Smith”, “Clifford”, “Albert”, “Aurora” y los algoritmos de ordenación (A, B, C) que son totalmente independientes de la lista. Estos algoritmos de ordenación pueden ser inyectados a lista.

Un poco de UML

El Problema

Vamos al código

Observaciones

  • Los perros no pueden volar pero aun asi tenemos el comportamiento volar().
  • Este diseño forzaría a cada subclase como perro, cocodrilo, mono a implementar el método volar().
  • Como todos sabemos no todos los animales pueden volar. Por lo tanto, no es correcto que todas las subclases tengan que implementarlo.

Usemos una interface

Una idea que nos puede venir a la cabeza para resolverlo es crear una interface volando que tenga el método volar. De esta forma solo los animales que pueden volar la implementarían.

¡Resolvimos el problema! Mmm espera… Hemos creado otro llamado “Duplicación de Código

Esto quiere decir que si tenemos 100 animales voladores tendremos 100 implementaciones de volar().

Qué pasa si tenemos que cambiar el método volar() para varias sub-clases? Pues tendriamos que abrir cada clase que lo implemente y modificarlo.

Solución

Aca tenemos el conjuto de algoritmos del que hablaba la definicion.

Vamos a hacerlos intercambiables.

… permite que el algoritmo varie independientemente de los clientes que lo utilicen.

Ventajas de este diseño

  • Otros tipos de objetos pueden reusar los diferentes comportamientos (VolarBajito, VolarAlto o NoVuelo) porque no estan ocultos en nuestras clases Animal.
  • Podemos agregar nuevos comportamientos sin modificar niguno de los existentes o teniendo que tocar nuestras clases Animal.
  • Podemos cambiar el comportamiento en tiempo de ejecucion dinamicamente.

El código

Animal

package com.palmer;


public abstract class Animal {

    private String nombre;

    private IVolando vuelo;

    Animal(){}

    Animal(String nombre){

        this.nombre = nombre;

    }

    public String getNombre() {
        return nombre;
    }

    public abstract void hacerSonido();


    public void setVuelo(IVolando vuelo){

        this.vuelo = vuelo;

    }

    public void mostrarVuelo(){

        this.vuelo.volar();

    }

}

Pajaro

package com.palmer;

public class Pajaro extends Animal {


    public void hacerSonido() {

        System.out.println("Soy un pajaro y hago sonidos de pajaro");

    }

}

Perro

package com.palmer;

public class Perro extends Animal {

    public void hacerSonido() {

        System.out.println("Soy un pajaro y hago sonidos de perro => Guau Guau");

    }

}


IVolando

package com.palmer;

public interface IVolando {

    public void volar();

}

VolandoAlto

package com.palmer;

public class VolandoAlto implements IVolando {

    public void volar() {

        System.out.println("Volando Alto");
        System.out.println("1: Tomar un muchaaaa energia");
        System.out.println("2: Abrir mis alas");
        System.out.println("3: Mantener minimo 300 pies.");

    }
}

VolandoBajito

package com.palmer;


public class VolandoBajito implements IVolando{


    public void volar() {

        System.out.println("Volando Bajito");
        System.out.println("1: Tomar un poco de energia");
        System.out.println("2: Abrir mis alas");
        System.out.println("3: Mantener maximo 50 pies.");

    }
}


Main

package com.palmer;

public class Main {

    public static void main(String[] args) {

        //habilidades para volar
        VolandoBajito vueloBajito = new VolandoBajito();
        VolandoAlto vueloAlto = new VolandoAlto();
        NoVuelo noVuelo = new NoVuelo();

        //pajarito pequeno
        Animal pajaroPequeno = new Pajaro();
        pajaroPequeno.setVuelo(vueloBajito);

        //pajaro grande
        Animal pajaroGrande = new Pajaro();
        pajaroGrande.setVuelo(vueloAlto);

        //un perro x
        Animal perro = new Perro();
        perro.setVuelo(noVuelo);

        //probando habilidades para volar
        perro.mostrarVuelo();
        pajaroPequeno.mostrarVuelo();
        pajaroGrande.mostrarVuelo();

    }
}

 

Leave a reply:

Your email address will not be published.

Site Footer