Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Patrón Observador.

Estas en el tema de Patrón Observador. en el foro de Frameworks y PHP orientado a objetos en Foros del Web. 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 ...
  #1 (permalink)  
Antiguo 29/05/2006, 10:22
 
Fecha de Ingreso: septiembre-2005
Mensajes: 142
Antigüedad: 18 años, 7 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
  #2 (permalink)  
Antiguo 29/05/2006, 12:35
 
Fecha de Ingreso: abril-2006
Mensajes: 62
Antigüedad: 18 años
Puntos: 0
Pregunta dale para adelante

gracias otra vez por el artículo.

Aprovecho para preguntarte que pasó con aquel ejemplo de MVC que te habías propuesto hacer.

Modestamente creo que lo que hace falta en realidad es un "working example" al respecto, pero que sea exclusivamente para ilustrar los conceptos. Es decir que deje bien claro las responsabilidades de cada componente, pero sin pretender que haga algo útil en verdad, solo mostrar algunos párrafos.. No sé si me explico, solo lo mínimo indispensable.

En ese caso no necesitaría usar abstracción de base datos por PEAR, ni usar Smarty y sería más sencillo de escribir y leer.

Digo esto porque actualmente estoy buscando material sobre este patrón de diseño y ningún ejemplo baja de las 300 líneas de código.

En el caso de que no encuentre uno, voy a tratar de escribirlo cuando termine de entender bien, pero me gustaría saber tu opinión al respecto, si es que te parece una buena idea o no.
__________________
Guish
  #3 (permalink)  
Antiguo 29/05/2006, 12:59
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Muy bueno y completo.

Tengo borradores con varios patrones de diseño, hechos en PHP5 y lo más sencillos posibles (dicen que "La simplicidad es la máxima sofisticación" ). Estos tratando de reservarme algo de tiempo para completar los textos y subirlos a mi blog, pero ultimamente mi nivel de "procrastinacion" está muy alta.

Pero el que me falta armar es uno sobre MVC. Tengo los conceptos generales claros, pero he visto muchos ejemplos y código, y cual más entreverado (¿por qué costará tanto hacer las cosas simples?).

Si se te ocurre como armar uno bien sencillo, con lo mínimo posible, estaré muy feliz de leerlo.
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #4 (permalink)  
Antiguo 29/05/2006, 14:26
 
Fecha de Ingreso: septiembre-2005
Mensajes: 142
Antigüedad: 18 años, 7 meses
Puntos: 3
Actualmente para desarrollar un Modelo-Vista-Controlador que cubra las necesidades básicas se necesita código muy por encima de las 300 linias te lo aseguro. El hecho de no utilizar librerias lo haría aún superior. Para mi entender los componentes para un mini -Model View Controller serían los siguientes:

Dispatcher
Router
View
Model (ActiveRecord, RowSet, Row)
Config

De hecho desarrollé un miniFramework pero en aquella época trabajaba en dos empresas además de estudiar la carrera en la universidad así que se me hizo difícil sobre todo el proceso de documentación. También entendí que programarlo todo de un tirón sería totalmente inútil. Creo que la manera más efectiva es programarlo a modulos poniendo ejemplos y al final de todo juntarlos. De hecho últimamente estoy posteando ejemplos de patrones aplicados en el MVC. Si os parece bien intentaría empezar por la construción del Modelo. Cuando lo tenga documentado ya os avisaré. También podeis ayudar si quereis eh!
  #5 (permalink)  
Antiguo 29/05/2006, 14:36
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Mmmm ... de eso hablo entonces! De armar un ejemplo "extremadamente básico" para luego armar otro más complejo. Esto es lo que estoy tratando de evitar.

Por ejemplo, un caso con las 3 clases básicas (Modelo, Vista y Controlador), y que lo único que haga es representar con código la definición del patrón (el controlador recibe las peticiones, decide si va contra la vista o contra el modelo, etc).

Creo que esto ayuda a que la gente que no domina el tema, puede empezar a entenderlo sin miedo.

Ejemplos completos (y complejos) se encuentran, lo que no he visto es "él ejemplo inicial", el "caso base", donde menos código ya no cumpliría con el patrón
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #6 (permalink)  
Antiguo 30/05/2006, 07:18
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Les propongo que este tipo de ejemplos una vez depurados si corresponde con las acotaciones de cada uno de los que participen en el tema sea colocado como una FAQ en este foro.

(Las FAQ's las pueden publicar Uds. mismos sin más .. se trata sólo de "responder" el mensaje de FAQ's)

Un saludo,
__________________
Por motivos personales ya no puedo estar con Uds. Fue grato haber compartido todos estos años. Igualmente los seguiré leyendo.
  #7 (permalink)  
Antiguo 30/05/2006, 12:33
 
Fecha de Ingreso: septiembre-2005
Mensajes: 142
Antigüedad: 18 años, 7 meses
Puntos: 3
De hecho no creo que se pueda explicar todo en una FAQ acabaría siendo engorroso, tendría que ser más bien en un artículo que fuera acompañado por un foro por las preguntas que se generarian, una FAQ podría hacerse sobre patrones quizá. Sería buena idea.
  #8 (permalink)  
Antiguo 31/05/2006, 06:46
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Cita:
Iniciado por Casuis
De hecho no creo que se pueda explicar todo en una FAQ acabaría siendo engorroso, tendría que ser más bien en un artículo que fuera acompañado por un foro por las preguntas que se generarian, una FAQ podría hacerse sobre patrones quizá. Sería buena idea.
Ok, .. no obstante se puede crear una FAQ simple que apunte con un link a este mensaje (o série de mensajes) que hablan sobre patrones y demás. El caso es que no quede en el "olvido" cuando ya no apareza este mensaje en la prímera página de resultados de este sub-foro. Principalmente ese es el objetivo.

Y bueno, .. no lo hago yo por qué UDs. mejor que yo saben que título dar a esa supuesta FAQ y alguna breve intruducción + el o los "links" que correspondan hacia mensajes u otros sitios.

Un saludo,
__________________
Por motivos personales ya no puedo estar con Uds. Fue grato haber compartido todos estos años. Igualmente los seguiré leyendo.
  #9 (permalink)  
Antiguo 31/05/2006, 07:27
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
"¡Si, Boss!"

PD: parafraseando a "Prison Break"
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #10 (permalink)  
Antiguo 26/05/2007, 17:00
 
Fecha de Ingreso: mayo-2007
Mensajes: 2
Antigüedad: 17 años
Puntos: 0
Re: Patrón Observador.

Hola Casius...
En el ejemplo que pones para mostrar como funciona el patrón Observer tengo una duda. Cómo podría "inscribir" un nuevo inversionista para que reciba las notificaciones de forma dinámica, y cómo la clase IBM podrá garantizarme que a el nuevo inversionista le van a llegar las notificaciones en la aplicación. Si yo no voy a estar registrado en la página index.php.
Espero que se entienda mi pregunta, pues no se explicarme mejor...
Saludos
K@
  #11 (permalink)  
Antiguo 26/05/2007, 21:18
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Patrón Observador.

Deberias de especificar mas tu pregunta, el patron observador es muy util, pero creo te refieres a un modo persistente, ej: Notificar a todos los usuarios registrados en la base de datos que algo cambio, por lo que tienes que modificar como vas a manejar y almacenar tus usuarios para notificarles.

Saludos.
  #12 (permalink)  
Antiguo 27/05/2007, 21:13
 
Fecha de Ingreso: mayo-2007
Mensajes: 2
Antigüedad: 17 años
Puntos: 0
Re: Patrón Observador.

"Deberias de especificar mas tu pregunta, el patron observador es muy util, pero creo te refieres a un modo persistente, ej: Notificar a todos los usuarios registrados en la base de datos que algo cambio, por lo que tienes que modificar como vas a manejar y almacenar tus usuarios para notificarles.
"


Si, gracias por la aclaración, eso es exactamente a lo que me refiero, porque siempre que veo ejemplos de implementar estos patrones son utilizando listas de objetos que se pasan en la pagina "index.php" de cada ejemplo de forma estática, pero si quiero implementarlo en un sistema tendría que cargar la lista de los "Observers" desde una tabla de la base de datos para informarles cada vez que existe un evento de su interés??? O podría existir alguna manera de hacer persistentes estos objetos sin que existan en la base de datos? (espero que esta última pregunta no suene muy tonta..)
Un saludo..
K@
  #13 (permalink)  
Antiguo 28/05/2007, 07:52
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Re: Patrón Observador.

Hacer objetos persistentes puede ser en muchas formas no solo en una base de datos, hay archivos de texto, estructuras, archivos XML, pero si en su base todos requieren de cierta forma ser serializables.

Y como te comente, es lo mismo, utilizas el mismo patron, la unica diferencia es a la hora de utilizarlo ej:

En lugar de esto:
Código PHP:
$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); 
Utilizas algo asi:
Código PHP:
// Crea el stock IBM y añade a los inversores
$ibm = new IBM("IBM"120.00);

// Seleccionas de tu base de datos tus inversores
foreach( $rst->fetch() as $person ) {
     
$i = new Inversor($person['name']);
     
$ibm->Attach$i );
     
$i null// Borramos el objeto
}

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

Última edición por GatorV; 19/07/2011 a las 16:50
  #14 (permalink)  
Antiguo 31/05/2007, 02:27
 
Fecha de Ingreso: mayo-2007
Mensajes: 41
Antigüedad: 17 años
Puntos: 0
Re: Patrón Observador.

Muchas gracias por compartir vuestros conocimientos!!
Yo estoy tratando de iniciarme y profundizar en los patrones de diseño en PHP5.
Y vuestros post en el foro, y en blogs de algunos de vosotros encuentro bastantes respuestas a mis dudas.

Para mí, que estoy informándome ahora sobre este tema, me sería muy útil tener pequeños ejemplos de cada uno de los diferentes patrones de diseño. Y un ejemplo más complejo que englobara los más utilizados y más útiles, que pudiera servir como base para realizar aplicaciones web.

Quizás esto ya documentado en algún lugar de la web, pero no yo no lo he encontrado. Por lo que estoy agrupando la información que vais facilitando sobre cada uno de los diferentes patrones, y cuando los tenga todos bien claros procuraré hacer lo que comentaba, unir en una sola aplicación los que se consideren más útiles.

Muchas gracias de nuevo.
  #15 (permalink)  
Antiguo 31/05/2007, 07:16
 
Fecha de Ingreso: noviembre-2003
Mensajes: 798
Antigüedad: 20 años, 5 meses
Puntos: 8
Re: Patrón Observador.

Five common PHP design patterns
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Tema Cerrado

SíEste tema le ha gustado a 3 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 01:32.