IoC & Dependency Injection


Germán Lena / @german_lena

IoC - Inversión de control



Es un método por el cuál el control del flujo de programación no lo da el código programado por nosotros sino por el framework que estemos utilizando.

Don't call us, we'll call you



Martin Fowler lo define como "Hollywood Principle"

IoC



Se puede considerar la principal diferencia entre framework y librería. La librería es algo que usamos y llamamos cuando necesitamos. El framework orquesta toda nuestra aplicación.

IoC



Se puede decir que es lo que nos ayuda a abstraernos para desarrollar solo nuestra aplicación y que el framework se encargue de la trivialidad de, por ejemplo, toda la capa HTTP de una web.

Principio de Inyección de dependencias



Es un concepto desarrollado a Robert C. Martin y es una de las respuestas para dos de los principios solid: Open/Close y Liskov substitution

Principio de Inyección de dependencias



Uno de los principales problemas en el desarrollo es el acoplamiento. Para solucionarlo, las clases de capas superiores deberían depender de abstracciones y no de implementaciones de clases inferiores (y viceversa).

Principio de Inyección de dependencias



Inyección de dependencias es cuando el ContenedorDI (biblioteca, framework, módulo místico que armamos) inyecta a un objeto las dependencias del mismo.

Principio de Inyección de dependencias



Permite que nuestro código dependa de abstracciones que "alguien" va a resolver sin necesidad de que tengamos que explicitarlas al instanciar o invocar un método.

Ejemplo

										
class ShoppingCart {
	
    protected $paymentMethod;

    public function __construct() {
        $this->paymentMethod = new CreditCardPaymentMethod();
    }

}        
        
										
								

Ejemplo

										
class CreditCardPaymentMethod {
	
    public function validate()
    ...

}    
class DirectDepositPaymentMethod {
	
    public function validate()
    ...

}        
										
								

Ejemplo

										
interface IPaymentMethod {

    public function validate();

}
class CreditCardPaymentMethod implements IPaymentMethod {
	
    public function validate()
    ...

}    
class DirectDepositPaymentMethod implements IPaymentMethod {
	
    public function validate()
    ...

}        
										
								

Ejemplo

										
class ShoppingCart {
	
    protected $paymentMethod;

    public function __construct(IPaymentMethod $paymentMethod) {
        $this->paymentMethod = $paymentMethod;
    }

}         
										
								

Ejemplo

										
$shoppingCart = new ShoppingCart(new CreditCardPaymentMethod());       
										
								

Ejemplo

										
class PaymentMethodEnum {
    const CREDIT_CARD = 1;
    const DIRECT_DEPOSIT = 2;
}   
										
								

Ejemplo

										
class ShoppingCartFactory {
    public function Create ($idPaymentType) {
        $method = null;

        switch ($idPaymentType) {
            case PaymentMethodEnum::CREDIT_CARD: 
                $method = new CreditCardPaymentMethod(); 
                break;
            case PaymentMethodEnum::DIRECT_DEPOSIT: 
                $method = new DirectDepositPaymentMethod();  
                break;
            default: 
                throw new InvalidMethodException();
        }

        return new ShoppingCart($method);
    }
}  
										
								

Ejemplo

										
$factory = new ShoppingCartFactory();
$shoppingCart = $factory->Create(Input::get('selectedMethod'));     
										
								

FIN

Referencias

  • http://martinfowler.com/bliki/InversionOfControl.html
  • http://martinfowler.com/articles/injection.html
  • http://danielggarcia.wordpress.com/2014/01/15/inversion-de-control-e-inyeccion-de-dependencias/