Cita:
El diseño uml del patrón: El patrón Obervador define una dependencia del tipo uno-a-muchos entre objetos, de manera que cuando uno de los objetos cambia su estado, el observador de encarga de notificar este cambio a todos los otros dependientes.
Este patrón también se conoce como el patrón de publicación-suscripción o modelo-vista. Estos nombres sugieren las ideas básicas del patrón, que son bien sencillas: el objeto de datos, llamémoslo "Sujeto" a partir de ahora, contiene métodos mediante los cuales cualquier objeto observador o vista se puede suscribir a él pasándole una referencia a si mismo. El Sujeto mantiene así una lista de las referencias a sus observadores.
Los observadores a su vez están obligados a implementar unos métodos determinados mediante los cuales el Sujeto es capaz de notificar a sus observadores "suscritos" los cambios que sufre para que todos ellos tengan la oportunidad de refrescar el contenido representado. De manera que cuando se produce un cambio en el Sujeto, ejecutado, por ejemplo, por alguno de los observadores, el objeto de datos puede recorrer la lista de observadores avisando a cada uno.
Este patrón también se conoce como el patrón de publicación-suscripción o modelo-vista. Estos nombres sugieren las ideas básicas del patrón, que son bien sencillas: el objeto de datos, llamémoslo "Sujeto" a partir de ahora, contiene métodos mediante los cuales cualquier objeto observador o vista se puede suscribir a él pasándole una referencia a si mismo. El Sujeto mantiene así una lista de las referencias a sus observadores.
Los observadores a su vez están obligados a implementar unos métodos determinados mediante los cuales el Sujeto es capaz de notificar a sus observadores "suscritos" los cambios que sufre para que todos ellos tengan la oportunidad de refrescar el contenido representado. De manera que cuando se produce un cambio en el Sujeto, ejecutado, por ejemplo, por alguno de los observadores, el objeto de datos puede recorrer la lista de observadores avisando a cada uno.
Bien ahora pasando al ejemplo práctico sería de la siguiente manera:
Imaginamos que tenemos inversores en IBM y quieren saber que cuando cambien el valor de las acciones se les notifique. Es un claro ejemplo de tener observador y /o observadores a los cuales se les notificará el cambio.
Comencemos con el código (por cierto está optimizado para PHP5):
primero declararemos las interfaces. class.Observed.php
Código PHP:
interface Observed{
function Attach(Inversor $inversor);
function Detach(Inversor $inversor);
}
Código PHP:
interface Observer{
function Update(Stock $stock);
}
Código PHP:
abstract class Stock implements Observed {
protected $_simbolo;
protected $_precio;
private $_inversores = array();
// Constructor
public function __construct($simbolo, $precio)
{
$this->_simbolo = $symbol;
$this->_precio = $precio;
}
public function Attach(Inversor $inversor)
{
$this->_inversores["$inversor"] = $inversor;
}
public function Detach(Inversor $inversor)
{
if(isset($this->_inversores["$inversor"]))
unset($this->_inversores["$inversor"]);
}
public function showInversores()
{
foreach ($this->_inversores as $inversor)
echo $inversor."<br />";
}
public function Notify(){
foreach ($this->_inversores as $inversor){
$inversor->update($this);
}
echo "<br />";
}
// Propiedades
public function setPrecio($precio){
$this->_precio = $precio;
$this->Notify();
}
public function getPrecio(){
return $this->_precio;
}
public function setSimbolo($simbolo){
$this->_simbolo = $simbolo;
}
public function getSimbolo(){
return $this->_simbolo;
}
}
Código PHP:
class Inversor implements Observer
{
private $_nombre;
private $_stock;
public function __construct($nombre){
$this->_nombre = $nombre;
}
public function Update(Stock $stock){
echo "Notificado a $this->_nombre El precio nuevo es->".$stock->getPrecio(). "€<br />";
}
public function __toString(){
echo "el nombre->$this->_nombre";
}
}
Código PHP:
function __autoload($nombreClase){
require_once("class.".$nombreClase.".php");
}
// Observador concreto
class IBM extends Stock {
public function __construct($simbolo, $precio){
parent::__construct($simbolo, $precio);
}
}
$s = new Inversor("Juan");
$b = new Inversor("Maria");
// Crea el stock IBM y añade a los inversores
$ibm = new IBM("IBM", 120.00);
$ibm->Attach($s);
$ibm->Attach($b);
// cambia el precio, que le es notificado a los inversores
$ibm->setPrecio(120.10);
$ibm->setPrecio(121.00);
$ibm->setPrecio(120.50);
$ibm->setPrecio(120.75);
Cita:
Espero que les sirva de utilidad, al menos para entender el comportamiento del patrón. Notificado a Juan El precio nuevo es->120.1€
Notificado a Maria El precio nuevo es->120.1€
Notificado a Juan El precio nuevo es->121€
Notificado a Maria El precio nuevo es->121€
Notificado a Juan El precio nuevo es->120.5€
Notificado a Maria El precio nuevo es->120.5€
Notificado a Juan El precio nuevo es->120.75€
Notificado a Maria El precio nuevo es->120.75€
Notificado a Maria El precio nuevo es->120.1€
Notificado a Juan El precio nuevo es->121€
Notificado a Maria El precio nuevo es->121€
Notificado a Juan El precio nuevo es->120.5€
Notificado a Maria El precio nuevo es->120.5€
Notificado a Juan El precio nuevo es->120.75€
Notificado a Maria El precio nuevo es->120.75€