You are on page 1of 5

Utilzando o Design Pattern OBSERVER utilizando as interfaces SPL (STANDARD PHP LIBRARY)

criado por Marcus Brasizza em 11/09/2008 6:54am Definio: A utilizao um objeto que ser observado por um ou mais objetos , que so os observadores, que obviamente so associados como observadores deste objeto, e quando o observador disparar um mtodo de notificao, todos os objetos associados (os observadores) executaro cada um sua rotina especfica, assim fazendo com que o processo seja organizado e evitando colocar instancias de objetos dentro de outros objetos ou at mesmo um aninhado de instancias para cada objeto que ir executar algo. Utilizao: Utilizarem duas interfaces j disponveis no PHP chamadas de SplObserver e SplSubject, disponveis ds do comeo do PHP 5.1.xxxx - Interface SplSubject: a interface que ser implementada no Observado. contm os metodos attach e detach e notify -- attach: Adiciona observadores ao objeto. -- detach: Remove observadores. -- notify: Envia a notificao para todos os observadores do objeto. - Interface SplObject: a interface do observador. contm somente o mtodo update. NOTA: Todos os mtodos dessas interfaces, so explcitos em relao aos mtodos, chamados de type-hint, ou seja , para o mtodo attach s deve ser enviado como parmetro um objeto do tipo SplObserver, o mesmo para o detach, tudo isso existe uma documentao, e vou colocar um cdigo de exemplo. Desenvolvendo: Vamos primeiro criar a classe que ser observada pelos demais objetos, chamaremos ela de Materia
<?php class Materia implements SplSubject { private $nome_materia; // Os observadores um array onde ele guardar todas as instncias dos objetos que forem adicionados private $_observadores = array(); // Coloquei um array de log s para mostrar o funcionamento do Observer private $_log = array(); // Encapsuladores public function GET_materia() { return $this->nome_materia; }

function SET_log($valor) { $this->_log[] = $valor ; } function GET_log() { return $this->_log; } // Funo construtora que ir somente associar um nome ao professor function __construct($nome) { $this->nome_materia = $nome; $this->_log[] = " Materia $nome foi incluida com sucesso"; } // Implementa o mtodo attach do SplSubject, enviando como parmetro um observador e associando ao array de objetos public function attach(SplObserver $classes) { $this->_classes[] = $classes; $this->_log[] = " O ".$classes->GET_tipo()." ".$classes>GET_nome()." foi adicionado"; } // Implementa o mtodo detach do SplSubject, que somente remove a instncia do objeto public function detach(SplObserver $classes) { foreach ($this->_classes as $key => $obj){ if ($obj == $classes){ unset($this->_classes[$key]); $this->_log[] = " O ".$classes->GET_tipo()." ".$classes->GET_nome()." foi removido"; } } } // Implementa o mtodo notify do SplSubject, que percorre todo o array de observadores e chama o mtodo update de do observador, que esta implementado dentro da sua classe public function notify() { foreach ($this->_classes as $classes){ $classes->update($this); } } } ?>

Feito isso, criaremos uma classe de Professor.


<?php class Professor implements SplObserver { protected $tipo = "Professor"; private $nome; private $endereco;

private $telefone; private $email; // Encapsulador public function GET_tipo() { return $this->tipo; } public function GET_nome() { return $this->nome; } public function GET_email() { return $this->email; } public function GET_telefone() { return $this->nome; } // Construtor que somente associa o nome do function __construct($nome) { $this->nome = $nome; } professor

// Implementa o mtodo update do SplObserver, que executa o mtodo de acordo com a necessidade do objeto Professor public function update(SplSubject $object) { $object->SET_log("Vindo de ".$this->nome.": Dou aula de ".$object->GET_materia()); } } ?>

Criaremos agora uma classe de Aluno.


<?php class Aluno implements SplObserver { protected $tipo = "Aluno"; private $nome; private $endereco; private $telefone; private $email; // Encapsulador public function GET_tipo(){ return $this->tipo; } public function GET_nome() { return $this->nome; }

public function GET_email() { return $this->email; } public function GET_telefone() { return $this->nome; } // Construtor que somente associa o nome do function __construct($nome) { $this->nome = $nome; } aluno

// Implementa o mtodo update do SplObserver, que executa o mtodo de acordo com a necessidade do objeto Aluno public function update(SplSubject $object) { $object->SET_log("Vindo de ".$this->nome.": Sou aluno de ".$object->GET_materia()); } } ?>

Com as classes criadas, iremos associar os observadores na classe observada e depois notificaremos.
<?php require_once("professor.class.php"); require_once("aluno.class.php"); require_once("materia.class.php"); $materia = new Materia("Matematica"); $marcus = new Professor("Marcus"); $rafael = new Aluno("Rafael"); $vinicius = new Aluno("Vinicius"); // Associando os observadores no objeto Materia Matemtica $materia->attach($rafael); $materia->attach($vinicius); $materia->attach($marcus); $materia2 = new Materia("Portugues"); $renato = new Professor("Renato"); $fabio = new Aluno("Fabio"); $tiago = new Aluno("tiago"); // Associando os observadores no objeto Materia Portugues $materia2->attach($renato); $materia2->attach($vinicius); $materia2->attach($fabio); $materia2->attach($tiago); // Removendo Alunos da Materia 1 $materia->detach($rafael); // Notificando as 2 Matrias $materia->notify(); $materia2->notify();

echo "Materia 1 <br>"; echo "<pre>"; print_r($materia->GET_log()); echo "</pre>"; echo "<hr>"; echo "Materia 2 <br>"; echo "<pre>"; print_r($materia2->GET_log()); echo "</pre>"; ?>

O output esperado esse:


Materia 1 Array ( [0] [1] [2] [3] [4] [5] [6] )

=> Materia Matematica foi incluida com sucesso => O Aluno Rafael foi adicionado => O Aluno Vinicius foi adicionado => O Professor Marcus foi adicionado => O Aluno Rafael foi removido => Vindo de Vinicius: Sou aluno de Matematica => Vindo de Marcus: Dou aula de Matematica

------------------------------------------------------------------------------Materia 2 Array ( [0] [1] [2] [3] [4] [5] [6] [7] [8] )

=> => => => => => => => =>

Materia Portugues foi incluida com sucesso O Professor Renato foi adicionado O Aluno Vinicius foi adicionado O Aluno Fabio foi adicionado O Aluno tiago foi adicionado Vindo de Renato: Dou aula de Portugues Vindo de Vinicius: Sou aluno de Portugues Vindo de Fabio: Sou aluno de Portugues Vindo de tiago: Sou aluno de Portugues

Esse um exemplo simples de como utilizar um observer sem precisar colocar uma instncia do professor e aluno dentro da matria. Pode ser feito muito mais com isso, como por exemplo um observer que ao cadastrar uma pessoa, envia um email para o admin. Use a imaginao e espero que gostem Qualquer dvida, crtica, sugesto ou incentivo para escrever mais artigos, por favor envie um comentrio abaixo. Abraos!

You might also like