{"id":804,"date":"2010-05-03T11:21:24","date_gmt":"2010-05-03T09:21:24","guid":{"rendered":"http:\/\/www.davidrojas.net\/?p=804"},"modified":"2013-11-23T19:13:51","modified_gmt":"2013-11-23T18:13:51","slug":"videotutorial-patrones-de-diseno-en-php-observer-pattern","status":"publish","type":"post","link":"https:\/\/www.davidrojas.net\/index.php\/desarrollo-web\/videotutorial-patrones-de-diseno-en-php-observer-pattern\/","title":{"rendered":"Videotutorial: Patrones de dise\u00f1o en PHP &#8211; Observer Pattern"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.davidrojas.net\/wp-content\/uploads\/2010\/03\/screencast_php_patterns.png\" alt=\"\" title=\"screencast_php_patterns\" width=\"163\" height=\"104\" class=\"derecha alignright size-full wp-image-774\" \/>En este screencast voy a explicaros el patr\u00f3n de dise\u00f1o <em>Observer<\/em> (observador) en PHP, que consiste en crear objetos observables que mantienen una lista de observadores y les notifica a \u00e9stos de cualquier cambio en su estado, normalmente llamando a uno de sus m\u00e9todos. Este patr\u00f3n suele utilizarse para implementar un sistema de manejo de eventos distribuido, por ejemplo construir un sistema de logging en el que registramos el observador (clase que se ocupa de escribir el log) en cada objeto que queramos que env\u00ede mensajes al log.<br \/>\n<!--more--><\/p>\n<h3>Ver screencast (duraci\u00f3n: 12:09)<\/h3>\n<div class=\"video\">\n<iframe loading=\"lazy\" src=\"\/\/player.vimeo.com\/video\/80137775?portrait=0&amp;color=c00202\" width=\"490\" height=\"368\" frameborder=\"0\" webkitallowfullscreen mozallowfullscreen allowfullscreen><\/iframe>\n<\/div>\n<ul>\n<li><a href=\"https:\/\/mega.co.nz\/#!vcVAlSoI!d7WCJB9RrYbU8kHXNfOK6Ra0QpYUHiloly3PY0Nwmm0\" title=\"Descargar versi\u00f3n alta calidad\">Descargar videotutorial en alta calidad &#8211; MOV (22 MB)<\/a><\/li>\n<li><a href=\"https:\/\/mega.co.nz\/#!2ItTDSQD!fSsuc0xA4SLGyLcrpd-yIBtE-XQViouclwU6k7XX7B4\" title=\"Descargar versi\u00f3n iPod\/iPhone\">Descargar videotutorial optimizado para iPod\/iPhone &#8211; M4V (16 MB)<\/a><\/li>\n<\/ul>\n<p><\/p>\n<p>Pod\u00e9is ver el resto de screencasts en la <a href=\"http:\/\/www.davidrojas.net\/index.php\/category\/screencasts\/\" title=\"Videotutoriales de dise\u00f1o y desarrollo web, codeigniter, PHP, CSS3\">p\u00e1gina de videotutoriales<\/a>, o suscribiros al <a href=\"http:\/\/itunes.apple.com\/WebObjects\/MZStore.woa\/wa\/viewPodcast?id=326994250\" title=\"Enlace a videopodcast de David Rojas en iTunes\">podcast de iTunes<\/a>. Os recomiendo especialmente que no os perd\u00e1is los tutoriales de dos de los patrones m\u00e1s usados: el <a href=\"http:\/\/www.davidrojas.net\/index.php\/desarrollo-web\/screencast-patrones-de-diseno-en-php-singleton-pattern\/\">Singleton<\/a> y el <a href=\"http:\/\/www.davidrojas.net\/index.php\/desarrollo-web\/screencast-patrones-de-diseno-en-php-factory-pattern\/\">Factory Pattern<\/a>.<\/p>\n<h3>Ejemplo de implementaci\u00f3n<\/h3>\n<p>En primer lugar creamos la clase abstracta de la que heredar\u00e1n las clases observables, y el interfaz que implementar\u00e1n los observadores.<\/p>\n<pre lang=\"php\">\r\n<?php\r\nabstract class Observable{\r\n\tprotected $observers;\r\n\tfunction __construct(){\r\n\t\t$this->observers = array();\r\n\t}\r\n\t\r\n\tpublic function registrarObserver($observer){\r\n\t\tif(!in_array($observer, $this->observers)){\r\n\t\t    $this->observers[] = $observer;\r\n\t\t}\r\n\t}\r\n\t\r\n\tpublic function deregistrarObserver($observer){\r\n\t\tif(in_array($observer, $this->observers)){\r\n\t\t    $key = array_search($observer, $this->observers);\r\n\t\t    unset($this->observers[$key]);\r\n\t\t}\r\n\t}\r\n\t\r\n\tabstract public function notificarObservers();\r\n\t\r\n}\r\n\r\ninterface Observer{\r\n\tpublic function notificar($sender, $params);\r\n}\r\n?>\r\n<\/pre>\n<p>A continuaci\u00f3n creamos las clases espec\u00edficas, en este caso una clase observable y dos clases de logging que actuar\u00e1n de observadores.<\/p>\n<pre lang=\"php\">\r\n<?php\r\nclass MiObservable extends Observable{\r\n\t\r\n\tpublic function __construct(){\r\n\t\tparent::__construct();\r\n\t}\r\n\t\r\n\tpublic function notificarObservers(){\r\n\t\tforeach ($this->observers as $observer) {\r\n\t\t\t$observer->notificar($this, $this->param);\r\n\t\t}\r\n\t}\r\n\t\r\n\tpublic function Evento($texto){\r\n\t\t$this->param = $texto;\r\n\t\t$this->notificarObservers();\r\n\t}\r\n}\r\n\r\nclass Log implements Observer{\r\n\tpublic function notificar($sender, $param){\r\n\t\techo get_class($sender).\" envio $param a las \".date('h:i:s', time()).\"<br \/>\";\r\n\t}\r\n}\r\n\r\nclass SalvarLog implements Observer{\r\n\tpublic function notificar($sender, $param){\r\n\t\techo \"Guardando en BD $param enviado por \".get_class($sender).\"... <br \/><br \/>\";\r\n\t}\r\n\t\r\n}\r\n?>\r\n<\/pre>\n<p>Para utilizarlo, instanciaremos las clases y registraremos los observadores de esta manera:<\/p>\n<pre lang=\"php\">\r\n<?php\r\n$obj = new MiObservable();\r\n$obj->registrarObserver(new Log());\r\n$obj->registrarObserver(new SalvarLog());\r\n\r\n$obj->Evento('Test 1');\r\nsleep(1);\r\n$obj->Evento('Test 2');\r\n\r\n$obj->deregistrarObserver(new SalvarLog());\r\n$obj->Evento('Test 3');\r\n?>\r\n<\/pre>\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En este screencast voy a explicaros el patr\u00f3n de dise\u00f1o Observer (observador) en PHP, que consiste en crear objetos observables que mantienen una lista de observadores y les notifica a \u00e9stos de cualquier cambio en su estado, normalmente llamando a uno de sus m\u00e9todos. Este patr\u00f3n suele utilizarse para implementar un sistema de manejo de [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,11,12],"tags":[],"class_list":["post-804","post","type-post","status-publish","format-standard","hentry","category-desarrollo-web","category-php","category-screencasts"],"_links":{"self":[{"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/posts\/804","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/comments?post=804"}],"version-history":[{"count":29,"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/posts\/804\/revisions"}],"predecessor-version":[{"id":984,"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/posts\/804\/revisions\/984"}],"wp:attachment":[{"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/media?parent=804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/categories?post=804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.davidrojas.net\/index.php\/wp-json\/wp\/v2\/tags?post=804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}