9.9. Estrategia: elegir el algoritno en tiempo de ejecución

Observe que el Template Method es el código que no cambia, y las funciones que sobreescribe son el código cambiante. Sin embargo, este cambio está fijado en tiempo de compilación, a través de la herencia. Siguiendo la máxima de preferir composición a herencia, se puede usar una composición para aproximar el problema de separar código que cambia de código que permanece, y generar el patrón Estrategia. Esta aproximación tiene un beneficio único: en tiempo de ejecución se puede insertar el código que cambia. Estrategia también añade un Contexto que puede ser una clase sucedánea que controla la selección y uso del objeto estrategia -¡igual que Estado!.

Estrategia significa exactamente eso: se puede resolver un problema de muchas maneras. Imagine que ha olvidado el nombre de alguien. Estas son las diferentes maneras para lidiar con esa situación:

//: C10:Strategy.cpp
// The Strategy design pattern.
#include <iostream>
using namespace std;

class NameStrategy {
public:
  virtual void greet() = 0;
};

class SayHi : public NameStrategy {
public:
  void greet() {
    cout << "Hi! How's it going?" << endl;
  }
};

class Ignore : public NameStrategy {
public:
  void greet() {
    cout << "(Pretend I don't see you)" << endl;
  }
};

class Admission : public NameStrategy {
public:
  void greet() {
    cout << "I'm sorry. I forgot your name." << endl;
  }
};

// The "Context" controls the strategy:
class Context {
  NameStrategy& strategy;
public:
  Context(NameStrategy& strat) : strategy(strat) {}
  void greet() { strategy.greet(); }
};

int main() {
  SayHi sayhi;
  Ignore ignore;
  Admission admission;
  Context c1(sayhi), c2(ignore), c3(admission);
  c1.greet();
  c2.greet();
  c3.greet();
} ///:~

Listado 9.21. C10/Strategy.cpp


Normalmente, Context::greet() sería más complejo; es el análogo de Template Method porque contiene el código que no cambia. Pero puede ver en main() que la elección de la estrategia puede realizarse en tiempo de ejecución. Llendo un paso más allá, se puede combinar esto con el patrón Estado y cambiar la Estrategia durante el tiempo de vida del objeto Contexto.