Patrón Estrategia (Strategy) en Java

Patrón Estrategia

Patrón Estrategia


¿Qué es el Patrón Estrategia ?

El Patrón Estrategia es un patrón de diseño que se encarga de definir el intercambio de mensajes entre diferentes objetos para realizar un comportamiento específico.

Pensemos por un momento, que somos un general de la antigua Roma, y vamos a realizar un ataque sobre Numancia. Para ello deberemos tener claro la estrategia a usar para los diferentes casos que se nos van a dar.

Como buen General, vamos a definir una serie de comportamientos para cada situación, si nos lanzan flechas, si salen con la caballería o la infantería.

Pues si trasladamos la estrategia usada en el campo de batalla, al desarrollo de Sotware, podríamos ver como el objetivo de este patrón es:

definir una serie de comportamientos, para elegir un algoritmo concreto en función de un contexto.

Ejemplo con Spring Boot

En este ejemplo vamos a implementar este Patrón haciendo uso de la Inyección de Dependencias con Spring Boot. Si tienes dudas sobre como funciona la Inyección de Dependencias en Spring pulsa aquí.

Esquema de patrón estrategia
Patrón estrategia

Crear la interfaz del Patrón Estrategia

Lo primero que vamos a hacer es crear una interfaz de la que el resto de clases van a implementar.

public interface AnimalStrategy {
    void doStuff();
    StrategyType getType();
}

A continuación definimos una clase enum, sera básica para decidir que tipo («getType») deberemos inyectar.

public enum StrategyType {
   DOG,
   CAT
}

Implementación de los algoritmos

A continuación vamos a implementar dos algoritmos en función, si el tipo es perro o gato:

public class IamADog  implements AnimalStrategy{
  @Override
  public void doStuff() {
      //implement algorithm Dog here 
  }
  @Override 
  public StrategyType getStrategyType() {
    return StrategyType.DOG;
  }
}
public class IamACat  implements AnimalStrategy{
  @Override
  public void doStuff() {
      //implement algorithm Dog here 
  }
  @Override 
  public StrategyType getStrategyType() {
    return StrategyType.CAT;
  }
}

Ahora mismo hemos definido dos clases diferentes, con dos algoritmos distintos que se ejecutarán en función de un tipo.

Estos dos algoritmos implementan una interfaz con una serie de métodos en común, porque la idea de este patrón es utilizar uno u otro en función de un comportamiento.

Creando la factoría

En este punto vamos a inyectar uno u otro algoritmo, vamos a almacenar en un map el tipo de estrategia, aunque podríamos utilizar algún otro mecanismo como un switch.

@Component
public class StrategyFactory {
  private Map<StrategyType, AnimalStrategy> strategies = new HashMap<StrategyType, AnimalStrategy>();
  
  public StrategyFactory(Set<AnimalStrategy> animalStrategy) {
     createStrategy(animalStrategy);
  }
  
  public AnimalStrategy findAnimalStrategy(StrategyType strategyType) {
     return strategies.get(strategyType);
  }

  private void createStrategy(Set<AnimalStrategy> animalStrategy) {
      animalStrategy.forEach( 
   strategy ->strategies.put(strategy.getStrategyType(), strategy));
 }
}

Utilizando el Patrón Estrategia

Haciendo uso de Spring y sus anotaciones vamos a inyectar la factoría que hemos creado. En este camos vamos inyectar la factoría que hemos creado mediante constructor, para ello hemos usado la anotación de lombok, @RequiredArgsConstructor. En este caso vamos a devolver el tipo animal Perro.

@Service
@RequiredArgsConstructor
public class AnimalService {

  private final StrategyFactory strategyFactory;

  public void findAnimal(String type){
  
     if (type.equalsIgnoreCase("dog") {    
        strategyFactory.findAnimalStrategy(StrategyType.DOG);
    }
  }
}

Conclusión

En esta entrada hemos visto la implementación del Patrón Estrategia con Spring. Podemos apreciar que es uno de los algoritmos más útiles y utilizados.

No te olvides de seguirnos en nuestras redes sociales Facebook o Twitter para estar actualizado.


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *