Instantly share code, notes, and snippets.

@mpratt /Ejemplo1.php
Last active Oct 12, 2016

Embed
What would you like to do?
Patrones de Diseño: Observador (Observer)
<?php
/**
* Clase Partido
* En este caso este es nuestro sujeto
*/
class Partido implements \SplSubject
{
protected $teams = array();
protected $observers = array();
public function __construct($team1, $team2)
{
$this->teams = array(
$team1 => 0,
$team2 => 0
);
}
public function gol($team)
{
$this->teams[$team]++;
$this->notify();
}
public function getScore()
{
$return = '';
foreach ($this->teams as $name => $score)
$return .= $name . ': ' . $score . ' | ';
return trim($return, ' | ');
}
/**
* La interface SplSubject nos obliga
* a implementar los siguientes métodos
*/
public function attach(\SplObserver $observer)
{
$id = spl_object_hash($observer);
$this->observers[$id] = $observer;
}
public function detach(\SplObserver $observer)
{
$id = spl_object_hash($observer);
if (isset($this->observers[$id]))
unset($this->observers[$id]);
}
public function notify()
{
foreach ($this->observers as $observer)
$observer->update($this);
}
}
/**
* Primer Observador Envia Email
*/
class Mail implements \SplObserver
{
public function update(\SplSubject $subject)
{
echo 'Enviando Email con marcador ' . $subject->getScore() . PHP_EOL;
mail('email@test.com', 'Hubo un gol', $subject->getScore());
}
}
/**
* Segundo Observador, guarda en un archivo
*/
class Log implements \SplObserver
{
public function update(\SplSubject $subject)
{
echo 'Guardando archivo con marcador ' . $subject->getScore() . PHP_EOL;
file_put_contents('partido.log', $subject->getScore(), FILE_APPEND);
}
}
$partido = new Partido('Colombia', 'Peru');
$partido->attach(new Mail());
$partido->attach(new Log());
$partido->gol('Colombia');
$partido->gol('Colombia');
$partido->gol('Peru');
echo $partido->getScore();
/**
* Resultado:
* Enviando Email con marcador Colombia: 1 | Peru: 0
* Guardando archivo con marcador Colombia: 1 | Peru: 0
*
* Enviando Email con marcador Colombia: 2 | Peru: 0
* Guardando archivo con marcador Colombia: 2 | Peru: 0
*
* Enviando Email con marcador Colombia: 2 | Peru: 1
* Guardando archivo con marcador Colombia: 2 | Peru: 1
* Colombia: 2 | Peru: 1
**/
?>
<?php
class User implements \SplSubject
{
protected $storage;
protected $name;
public function __construct(\SplObjectStorage $storage)
{
$this->storage = $storage;
}
public function add($name)
{
$this->name = $name;
$this->notify();
}
public function getName()
{
return $this->name;
}
public function attach(\SplObserver $observer)
{
$this->storage->attach($observer);
}
public function detach(\SplObserver $observer)
{
$this->storage->detach($observer);
}
public function notify()
{
foreach ($this->storage as $observer)
$observer->update($this);
}
}
class Logger implements \SplObserver
{
public function update(\SplSubject $subject)
{
printf('Log: Usuario %s creado %s' . PHP_EOL, $subject->getName(), date('H:i:s'));
}
}
class Security implements \SplObserver
{
public function update(SplSubject $subject)
{
if ($subject->getName() == 'pratt')
printf('Security: Alguien trató de crear el usuario %s' . PHP_EOL, $subject->getName());
}
}
$user = new User(new \SplObjectStorage());
$user->attach(new Logger());
$user->attach(new Security());
$user->add('carlos');
$user->add('pratt');
$user->add('miguel');
/**
* Resultado:
*
* Log: Usuario Carlos creado 19:43:32
* Log: Usuario pratt creado 19:43:32
* Security: Alguien trató de crear el usuario pratt
* Log: Usuario Miguel creado 19:43:32
*/
?>
<?php
class Shirt implements \SplSubject
{
protected $storage;
public function __construct(\SplObjectStorage $storage)
{
$this->storage = $storage;
}
public function buy()
{
// comprar ..
$this->notify('comprar');
}
public function sell()
{
// vender ..
$this->notify('vender');
}
public function attach(\SplObserver $observer)
{
$this->storage->attach($observer);
}
public function detach(\SplObserver $observer)
{
$this->storage->detach($observer);
}
public function notify($event = '')
{
foreach ($this->storage as $observer)
$observer->update($this, $event);
}
}
class Notify implements \SplObserver
{
public function update(\SplSubject $subject, $event = '')
{
if ($event == 'comprar')
echo 'Se compró una camisa' . PHP_EOL;
else if ($event == 'vender')
echo 'Se vendió una camisa' . PHP_EOL;
}
}
$camisa = new Shirt(new \SplObjectStorage());
$camisa->attach(new Notify());
$camisa->buy();
$camisa->sell();
$camisa->buy();
/**
* Resultado:
*
* Se compró una camisa
* Se vendió una camisa
* Se compró una camisa
*/
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment