INYECCIÓN DE DEPENDENCIAS EN PHP
Antes de explicar la inyección de dependencias hay que explicar el concepto de inversión de control que se puede definir como el proceso donde los objetos son suministrados a las clases que los necesitan, en lugar de crearlos ellos mismos. esto se puede ver fácilmente con un ejemplo sencillo:class Newsletter {
protected $mail ;
function __construct() {
$this -> mail = New Mailer ('correo@gmail.com', ...) ;
}
}
class Newsletter {
protected $mail;
function __construct() {
$this -> mail = $mail;
}
}
Ahora mismo estarás pensando que el problema no está solucionado todavía, que todavía has tenido que crear ese objeto Mail, configurarlo a mano y pasárselo a cada objeto que lo requiera. ¡Vamos paso a paso! La inyección de dependencias es un patrón de diseño, que trata de solucionar las necesidades de creación de los objetos de una manera práctica, útil, escalable y con una alta versatilidad del código y que nuestros objetos sean independientes comunicándose únicamente a través de un interface. Esto implica muchas modificaciones en el código fuente como el uso de implementaciones, la eliminación de la instanciación de objetos mediante la instrucción new o la necesidad de un modo de configuración que indique que clases se instanciarán en el caso de solicitarlo.
Para mostrar la inyección de dependencias en la práctica, vamos a ver un ejemplo muy sencillo. En este caso tenemos una clase llamada Database que requiere de un adaptador para poder comunicarse con la base de datos. En la primera versión del código se instancia el adaptador en el mismo constructor de la clase, lo que crea una dependencia muy fuerte entre estas dos partes del código. ësto hace que si en un futuro se necesita un cambio haya que cambiar el código.
Aquí tienes un ejemplo claro de inyección de dependencias en PHP, usando un enfoque basado en el constructor:
interface StorageInterface {
public function save(string $data): void;
}
// Implementación concreta de almacenamiento en archivo
class FileStorage implements StorageInterface {
public function save(string $data): void {
echo "Guardando '$data' en un archivo.\n";
// Lógica para guardar en archivo
}
}
// Implementación concreta de almacenamiento en base de datos
class DatabaseStorage implements StorageInterface {
public function save(string $data): void {
echo "Guardando '$data' en la base de datos.\n";
// Lógica para guardar en BD
}
}
// Implementación concreta de almacenamiento en archivo
class UserService {
private $storage;
// Inyección de dependencia a través del constructor
public function __construct(StorageInterface $storage) {
$this->storage = $storage;
}
public function saveUser(string $userData): void {
$this->storage->save($userData);
}
}
$fileStorage = new FileStorage();
$userServiceWithFile = new UserService($fileStorage);
$userServiceWithFile->saveUser("Usuario1"); // Guardando 'Usuario1' en un archivo.
// Inyectamos DatabaseStorage
$dbStorage = new DatabaseStorage();
$userServiceWithDb = new UserService($dbStorage);
$userServiceWithDb->saveUser("Usuario2"); // Guardando 'Usuario2' en la base de datos.