Last active
October 12, 2016 13:47
-
-
Save mpratt/5399005 to your computer and use it in GitHub Desktop.
Patrones de Diseño: Inyección de Dependencias
http://www.michael-pratt.com/blog/13/Patrones-de-Diseno-Inyeccion-de-Dependencias/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Logger | |
{ | |
protected $file; | |
public function __construct($file) { $this->file = $file; } | |
public function log($message) | |
{ | |
$message = date('H:i:s ') . $message . PHP_EOL; | |
return file_put_contents($this->file, $message, FILE_APPEND); | |
} | |
} | |
class Usuario | |
{ | |
protected $logger; | |
public function __construct() | |
{ | |
// Estamos instanciando el Logger dentro de la clase | |
$this->logger = new Logger('/usuario.log'); | |
} | |
public function logAction($message) | |
{ | |
$name = $this->getUserName(); | |
return $this->logger->log($name . ': ' . $message); | |
} | |
// Haz de cuenta que aquí van un par de métodos más | |
} | |
$user = new Usuario(); | |
if ($user->isLogged()) | |
{ | |
$user->logAction('Se enlogó correctamente'); | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Definimos una interface, con el metodo que | |
// es necesario para nuestra clase dependiente. | |
interface ILogger | |
{ | |
public function log($message); | |
} | |
// Implementamos la interface en la dependencia | |
class Logger implements ILogger | |
{ | |
// Basicamente el mismo contenido que en | |
// el ejemplo pasado | |
} | |
class Usuario | |
{ | |
protected $logger; | |
// Usamos el typehint ILogger para forzar que | |
// la dependencia debe implementar esa interface. | |
public function __construct(ILogger $logger) | |
{ | |
$this->logger = $logger; | |
} | |
// Haz de cuenta que aquí van un par de métodos más | |
} | |
// Fijate que la dependencia se esta inyectando desde afuera. | |
$user = new Usuario(new Logger('/archivo.log')); | |
if ($user->isLogged()) | |
{ | |
$user->logAction('Se enlogó correctamente'); | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Esta nueva clase implementa la interface ILogger | |
class DatabaseLogger implements ILogger | |
{ | |
public function __construct($dsn, $user, $password) | |
{ | |
$this->pdo = new PDO($dsn, $user, $password); | |
} | |
public function log($message) | |
{ | |
$stmt = $this->pdo->prepare('INSERT INTO table (date, message) VALUES (?,?)'); | |
return $stmt->execute(array(date('H:i:s'), $message)); | |
} | |
} | |
/** | |
* mira con que facilidad se puede intercambiar la dependencia | |
* siempre y cuando el nuevo objeto siga la interface pactada. | |
*/ | |
$databaseLogger = new DatabaseLogger(DSN, USER, PASSWORD); | |
$user = new Usuario($databaseLogger); | |
if ($user->isLogged()) | |
{ | |
$user->logAction('Se enlogó correctamente'); | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Usuario | |
{ | |
protected $logger; | |
// Ahora no usamos el constructor, sino que definimos | |
// un metodo para la inyección. | |
public setLogger(ILogger $logger) | |
{ | |
$this->logger = $logger; | |
} | |
// Haz de cuenta que aquí van un par de métodos más | |
} | |
$user = new Usuario(); | |
if ($user->isLogged()) | |
{ | |
$user->setLogger(new DatabaseLogger(DSN, USER, PASSWORD)); | |
$user->logAction('Se enlogó correctamente'); | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
interface IObjectB { public function calculate($value); } | |
interface IObjectC { public function convert($value); } | |
interface IObjectD { public function hash($value); } | |
class A | |
{ | |
protected $b; | |
public function __construct(IObjectB $b) { $this->b = $b; } | |
public function calculate($value) | |
{ | |
return $this->b->calculate($value); | |
} | |
} | |
class B implements IObjectB | |
{ | |
protected $c, $d; | |
public function __construct(IObjectC $c, IObjectD $d) | |
{ | |
$this->c = $c; | |
$this->d = $d; | |
} | |
public function calculate($value) | |
{ | |
$value = $this->c->convert($value); | |
return $this->d->hash($value); | |
} | |
} | |
class C implements IObjectC | |
{ | |
public function convert($value) { return intval($value); } | |
} | |
class D implements IObjectD | |
{ | |
public function hash($value) { return md5($value); } | |
} | |
$b = new B(new C(), new D()); | |
$a = new A($b); | |
echo $a->calculate(12345678); | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require('Pimple.php'); | |
class MyContainer extends Pimple | |
{ | |
public function __construct() | |
{ | |
$this['c'] = function () { return new C(); }; | |
$this['d'] = function () { return new D(); }; | |
$this['b'] = function ($c) { return new B($c['c'], $c['d']); }; | |
$this['a'] = function ($c) { return new A($c['b']); }; | |
} | |
} | |
$container = new MyContainer(); | |
$a = $container['a']; | |
echo $a->calculate(12345678); | |
/** | |
* Vale la pena aclarar que Pimple, a diferencia | |
* de la mayoria de IoCs, por defecto, siempre crea | |
* una instancia nueva del objeto que se pida. | |
* | |
* Para modificar ese comportamiento, se debe usar | |
* el metodo share(); y especificar ahí la construccion | |
* de los objetos. | |
*/ | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment