Inyección de comportamiento mediante composición
Tradicionalmente, la orientación a objetos ha utilizado la herencia para variar comportamientos: cada subclase redefine un método para implementar una versión distinta. Sin embargo, este enfoque tiende a crear jerarquías complejas y rígidas.
La alternativa es la composición flexible: una clase puede recibir como dependencia el comportamiento que necesita, sin crear subclases ni modificar su código.
Ejemplo: calculadora con comportamiento inyectado
#include <functional>
#include <iostream>
class Calculadora {
public:
using Operacion = std::function<int(int, int)>;
explicit Calculadora(Operacion op) : operacion_(op) {}
int ejecutar(int a, int b) const {
return operacion_(a, b);
}
private:
Operacion operacion_;
};
int main() {
Calculadora suma([](int a, int b) { return a + b; });
Calculadora producto([](int a, int b) { return a * b; });
std::cout << "5 + 3 = " << suma.ejecutar(5, 3) << "\n";
std::cout << "5 * 3 = " << producto.ejecutar(5, 3) << "\n";
}
Operaciones un alias destd::function<int(int,int)>, que puede almacenar cualquier operación binaria sobre enteros.Calculadorarecibe en su constructor el comportamiento a aplicar y lo guarda en el atributooperacion_.- El método
ejecutardelegará la acción en esa función inyectada. - En
main, se crean dos calculadoras distintas (suma y producto), usando lambdas como operaciones inyectadas.
Así, Calculadora no necesita subclases como CalculadoraSuma o CalculadoraProducto.
Su comportamiento se define desde fuera, en el momento de uso.
Este enfoque demuestra cómo la composición flexible permite variar el comportamiento de un objeto sin recurrir a la herencia, promoviendo diseños más modulares y mantenibles.