ProgramaciónDesarrollador C++

¿Qué es la delegación de responsabilidades (delegation) mediante la composición (composition) en C++? ¿Cómo se diferencia la composición de la herencia y cuándo se debe usar cada enfoque?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

La delegación de responsabilidades a través de la composición es una práctica de programación en la que un objeto de una clase contiene un objeto de otra clase (o clases) y los utiliza para implementar parte de su lógica, en lugar de heredar su interfaz.

Historia del tema

Las primeras versiones de OOP se centraron en la herencia, pero con el tiempo la práctica ha demostrado que la composición a menudo proporciona mayor flexibilidad, escalabilidad y reduce el acoplamiento entre componentes.

Problema

La herencia vincula objetos de manera rígida: los cambios en la clase base afectan a todos los descendientes, las jerarquías se vuelven complejas y surge la fragilidad de la arquitectura. La composición elimina estos problemas, permitiendo construir sistemas más confiables y mantenibles.

Solución

En C++, la delegación se implementa mediante la inclusión de un objeto de una clase como miembro de otra clase. En la clase envolvente, se llaman a los métodos del objeto anidado.

Ejemplo de código:

class Logger { public: void log(const std::string& msg) { std::cout << msg << std::endl; } }; class FileProcessor { Logger logger; // Composición public: void process(const std::string& filename) { logger.log("Processing file: " + filename); // ... } };

Características clave:

  • Acoplamiento más débil, flexibilidad
  • Posibilidad de cambiar el objeto delegado sobre la marcha
  • Más fácil de probar y mantener

Preguntas capciosas.

¿Puede la composición reemplazar completamente la herencia?

No, la herencia es necesaria donde se requiere una relación "es un" (is-a), mientras que la composición es cuando "tiene" (has-a). Por ejemplo, Button hereda de Widget, pero Car "tiene" Engine (composición).

¿Se puede cambiar el comportamiento del método delegado en composición?

Sí, los métodos de delegación se pueden adaptar sin tocar la clase original. También se puede cambiar dinámicamente el objeto delegado (por ejemplo, a través de un puntero o puntero único).

¿Es la composición más lenta que la herencia?

No, en la mayoría de los casos no hay diferencia de rendimiento. A veces, la herencia agrega costos por llamadas virtuales (vtable), mientras que la composición solo aumenta el tamaño del objeto.

Errores comunes y anti-patrón

  • Uso de herencia donde la composición es suficiente
  • Sobreespecificación de la composición con objetos anidados innecesariamente
  • "Inflar" clases con multitud de dependencias fragmentadas

Ejemplo de la vida real

Caso negativo

En el proyecto, todas las ventanas de diálogo heredaban de un DialogWindow común. La adición de nueva lógica de negocio conducía a código no funcional en todos los descendientes.

Ventajas:

  • Creación rápida al inicio
  • Reutilización de código

Desventajas:

  • Estructura rígida
  • Cualquier cambio afecta a todo el árbol

Caso positivo

Las funciones comunes se extrajeron en clases separadas (registro, validación), que se inyectan en cada diálogo a través de la composición.

Ventajas:

  • Flexibilidad
  • Fácil reemplazo de comportamiento

Desventajas:

  • Requiere diseño adicional
  • Puede llevar a una excesiva detallación