Design patterns Ocultar los detalles de la implementación de la estrategia.


Ejemplo

Una guía muy común en el diseño orientado a objetos es "lo menos posible pero lo necesario". Esto también se aplica al patrón de estrategia: por lo general, es recomendable ocultar los detalles de la implementación, por ejemplo, qué clases implementan las estrategias.

Para estrategias simples que no dependen de parámetros externos, el enfoque más común es hacer que la clase implementadora sea privada (clases anidadas) o paquete-privada y exponga una instancia a través de un campo estático de una clase pública:

public class Animal {

  private static class AgeComparator implements Comparator<Animal> {
    public int compare(Animal a, Animal b) {
      return a.age() - b.age();
    }
  }

  // Note that this field has the generic type Comparator<Animal>, *not*
  // Animal.AgeComparator!
  public static final Comparator<Animal> AGE_COMPARATOR = new AgeComparator();

  private final int age;

  Animal(int age) {
    this.age = age;
  }

  public int age() {
    return age;
  }

}

List<Animal> myList = new LinkedList<>();
myList.add(new Animal(10));
myList.add(new Animal(5));
myList.add(new Animal(7));
myList.add(new Animal(9));

Collections.sort(
  myList,
  Animal.AGE_COMPARATOR
);

El campo público Animal.AGE_COMPARATOR define una estrategia que luego se puede usar en métodos como Collections.sort , pero no requiere que el usuario sepa nada sobre su implementación, ni siquiera la clase implementadora.

Si lo prefieres, puedes usar una clase anónima:

public class Animal {

  public static final Comparator<Animal> AGE_COMPARATOR = new Comparator<Animal> {
    public int compare(Animal a, Animal b) {
      return a.age() - b.age();
    }
  };

  // other members...
}

Si la estrategia es un poco más compleja y requiere parámetros, es muy común usar métodos de fábrica estáticos como Collections.reverseOrder(Comparator<T>) . El tipo de retorno del método no debe exponer ningún detalle de implementación, por ejemplo, reverseOrder() se implementa como

public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
  // (Irrelevant lines left out.)
  return new ReverseComparator2<>(cmp);
}