+3

O Design Pattern Singleton, na prática

criado por Alex Weber em 01/06/2009 11:39pm
E se...

Agora vou apresentar o problema: E se a gente quisesse, por qualquer motivo, não só apenas somente poder ter uma instância da classe em qualquer devido momento mas ter sempre a mesma instância?

Parece fácil? Vamos ver na prática!

Vamos modificar a classe anterior para que armazene a hora em que foi criada e criar também um método para retornar o valor.

<?php

class SingletaoMelhorzinho{
       
// variável estática da classe
       
protected static $instance;
       
// variavel para a hora em que a classe foi instanciada
       
protected $hora;
       
       
// demarcado como private para evitar a instanciação direta
       
private function __construct()
       
{
               
// armazena a hora em que a classe é instanciada (de uma maneira legível para nós)
                $this
->hora = date('H:i:s');
       
}
       
       
// método para retornar a hora em que foi a classe foi instanciada
       
public function getTime()
       
{
               
return $this->hora;
       
}
       
       
// private para evitar que a classe seja clonada
       
private function __clone() { }
       
       
// método estático para poder ser chamado sem que exista uma instância da classe
       
public static function getInstance()
       
{
               
// verifica se a variável estática é uma instância de si mesmo
               
if(!self::$instance instanceof self){
                       
// se não for, a classe se instancia e armazena a instância na variável estática
                       
self::$instance = new self();
               
}
               
// retorna a variável estática
               
return self::$instance;
       
}
}

E vamos testar da seguinte maneira:
$foo = SingletaoMelhorzinho::getInstance();
echo
'A classe foi instanciada as ' . $foo->getTime();

Legal, agora dê alguns refresh... repare que a hora fica mudando.

Até aí isto é esperado né? Afinal não estamos usando sessões para armazenar a classe entre cada refresh.

Bom vamos então implementar sessões para ver se a gente consegue ter sempre a mesma instância do objeto inicializado na primeira vez que a página for carregada:

require_once('SingletaoMelhorzinho.php');
session_start
();

// IMPORTANTE! Como a classe será armazenada na sessão, faça o "include" dela antes de iniciar a sessão!

$_SESSION
['foo'] = SingletaoMelhorzinho::getInstance();
echo
'A classe foi instanciada as ' . $_SESSION['foo']->getTime();

Mas que p*** é essa Batiman?
Pois é... não funciona conforme o esperado...

A explicação é a seguinte: entre um refresh e o outro o objeto é serializado e "guardado pra depois". Quando a execução volta, o objeto serializado é "deserializado" e preparado para continuar funcionando normalmente.
O problema reside no fato de variáveis estáticas não serem serializadas.

E aí, será que existe alguma solução?

Comentários:

Mostrando 1 - 1 de 1 comentários
Show de bola cara!

Parabéns!
31/01/2011 2:45pm (~14 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)