LA COMPOSICIÓN EN PROGRAMACIÓN ORIENTADA A OBJETOS EN PHP

La composición es uno de los conceptos más importantes y poderosos en la Programación Orientada a Objetos. Se considera una de las mejores prácticas modernas y es ampliamente recomendada frente a la herencia en muchos escenarios.
La composición es una relación entre clases donde una clase contiene una o más instancias de otras clases. Se conoce como relación “tiene-un” (has-a).En lugar de heredar comportamiento de una clase padre, la clase se construye usando otras clases como partes o componentes.
La composición no solo promueve código más limpio, mantenible y flexible, sino que también sigue la filosofía moderna de diseño de software: “componer” en lugar de “heredar”.
Ejemplo:
  • Un Coche tiene un Motor, tiene un conjunto de Ruedas, tiene un Chasis, etc.
  • Un Usuario tiene una Dirección, tiene un Perfil, tiene una Cuenta Bancaria.

Ejemplo práctico en PHP

  • Versión con Herencia (menos recomendada):

    class Notificacion {
        public function enviar() {
       echo "Enviando notificación básica\n";
        }
    }
    
    class NotificacionEmail extends Notificacion {}
    class NotificacionSMS extends Notificacion {}
    class NotificacionPush extends Notificacion {}
    
    // Ahora vienen los problemas...
    class NotificacionEmailY SMS extends NotificacionEmail {}
    class NotificacionEmailYPush extends NotificacionEmail {}
    class NotificacionSMSEmailPush extends NotificacionSMS {}  // Explosión de clases
    class NotificacionEmailConAdjunto extends NotificacionEmail {}
    
    Problemas:
    • Si se quieren combinar 3 o 4 formas de notificación se producirá una explosión de clases.
    • Difícil mantener y extender.
    • Muchas clases casi idénticas.
  • Usando Composición:

    // 1. Se definen los "comportamientos" por separado
    interface CanalNotificacion {
        public function enviar(string $mensaje): void;
    }
    
    class CanalEmail implements CanalNotificacion {
        public function enviar(string $mensaje): void {
       echo "Enviando por Email: $mensaje\n";
        }
    }
    
    class CanalSMS implements CanalNotificacion {
        public function enviar(string $mensaje): void {
       echo "Enviando por SMS: $mensaje\n";
        }
    }
    
    class CanalPush implements CanalNotificacion {
        public function enviar(string $mensaje): void {
       echo "Enviando Push Notification: $mensaje\n";
        }
    }
    
    class CanalWhatsApp implements CanalNotificacion {
        public function enviar(string $mensaje): void {
       echo "Enviando por WhatsApp: $mensaje\n";
        }
    }
    
    // 2. La clase principal se compone de los canales que necesite
    class Notificador {
        /** @var CanalNotificacion[] */
        private array $canales = [];
    
        public function agregarCanal(CanalNotificacion $canal): void {
       $this->canales[] = $canal;
        }
    
        public function notificar(string $mensaje): void {
       foreach ($this->canales as $canal) {
      $canal->enviar($mensaje);
       }
        }
    }
    //Uso
    $notificador = new Notificador();
    
    $notificador->agregarCanal(new CanalEmail());
    $notificador->agregarCanal(new CanalPush());
    $notificador->agregarCanal(new CanalWhatsApp());
    
    $notificador->notificar("Su pedido ha sido enviado.");
    
    Ventajas:
    • Se pueden combinar cualquier cantidad de canales.
    • Se pueden nuevos canales, como Telegram, Slack, etc., sin tocar la clase "Notificador".
    • Fácil de configurar por usuario (cada usuario tiene sus canales preferidos).