Ver Mensaje Individual
  #1 (permalink)  
Antiguo 29/05/2006, 10:22
Casuis
 
Fecha de Ingreso: septiembre-2005
Mensajes: 142
Antigüedad: 18 años, 8 meses
Puntos: 3
Patrón Observador.

Buenas voy a escribir sobre el patrón observador uno de los más utilizados en el ámbito web. Sobre todo porque es aplicable al Modelo-Vista-Controlador. Para empezar una explicación de la wikipedia:
Cita:
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.
El diseño uml del patrón:


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);

y la interfaz class.Observer.php
Código PHP:
interface Observer{
    
    function 
Update(Stock $stock);

Muy bien ahora crearemos la clase abstracta class.Stock.php que será la encargada de notificar los cambios a los observadores.
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;
    }


Y finalmente creamos la clase Inversor. class.Inversor.php. Que resultarán los receptores de la notificación.
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";
    }

Finalmente el archivo index.php que construirá el ejemplo. Instanciara una clase stock le añadirá los inversores y cuando cambie el precio se lo notificará.
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); 
El resultado por pantalla será el siguiente:
Cita:
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€
Espero que les sirva de utilidad, al menos para entender el comportamiento del patrón.

Última edición por Casuis; 29/05/2006 a las 10:39