Skip to content

Instantly share code, notes, and snippets.

@mpratt
Last active October 12, 2016 13:47
Show Gist options
  • Save mpratt/5399005 to your computer and use it in GitHub Desktop.
Save mpratt/5399005 to your computer and use it in GitHub Desktop.
<?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');
}
?>
<?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');
}
?>
<?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');
}
?>
<?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');
}
?>
<?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);
?>
<?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