0

Série Design Patterns com PHP: I - Singleton

criado por Adler Medrado em 18/07/2006 3:24pm
O que é design pattern?
São formas de se escrever código de programação utilizando conceitos de melhores práticas de programação que visam mostrar soluções para problemas comuns no desenvolvimento de software.

O que é o singleton?
É um padrão de design de software (Design Pattern) que garante a existência
de uma única instância de uma classe, permitindo um acesso global a esta instância.

Quando é necessário utilizar?
Muitos projetos necessitam de classes que sejam instanciadas apenas uma vez, por exemplo:
Classes de Logging, conexão com banco de dados, entre outras.

Quais os pre-requisitos para se aproveitar melhor este artigo?
Conhecimento dos conceitos de programação orientada a objetos.
Conhecimentos das funcionalidades OO do PHP5.

Comentários:

Mostrando 1 - 10 de 15 comentários
augustowebd disse:
salve a todos,
estive estudando o padrão singleton e vendo vários exemplos de sua aplicabilidade e cheguei a uma dúvida:
"é correto dizer que usamos o padrão siglenton para conexões a db?", me pergunto pq veja bem:
- Se temos uma projeto, consistente, de uma aplicacao onde temos nossas áreas bem definidas e sabemos que na área A o usuário só irá efetua login( consulta ), na área B ele só visualizará relatórios( consulta ), sem falar de que cada ação permitida à tal usuário vai ser de acordo sua permissao, ou seja, dependendo do tipo de permissão do usuário em questão ele jamais efetuará uma alteração no banco, então o projetista do sistema acha interessante usar singleton para estabelecer uma conexao ao DB, temos no mínimo um impasse:
1º - Estabelecer varias conexões diferentes, de acordo apermissao.
2º - estabelecer uma conexao com excesso de permissao para um usuário que, de antemão, sabemos que não usará todos os recursos disponiveis pela conexao, o que em meu ponto de vista dá margem para insegurança.

Ae eu pergunto, é correto usar singleton para estabelecer conexões com banco de dados?
30/10/2006 8:18am (~10 anos atrás)

Eziel disse:
Apenas algumas sugestões e observações:
Vejamos uns exemplos com o código a seguir:

---------------------------------
<?php
class Exemplo {
public static $instance;

private function Exemplo()
{
}

public static function getInstance()
{
if (!isset(self::$instance)) {
Exemplo::$instance = new Exemplo();
}
return Exemplo::$instance;
}
}
$a = Exemplo::getInstance();
var_dump ( $a );

$a = Exemplo::getInstance();
var_dump ( $a );

$b = clone $a;
var_dump ( $b );
?>
---------------------------------
Executando temos:

---------------------------------
$ php exemplo.php
object(Exemplo)#1 (0) {
}
object(Exemplo)#1 (0) {
}
object(Exemplo)#2 (0) {
}
---------------------------------


Nota-se que obtendo a instância através do método getInstance(), realmente sempre obtemos a mesma instância da classe ( object(Exemplo)#1 ). Mas quando clonamos um objeto, utilizamos a palavra chave "clone", obtemos uma nova instância da classe ( object(Exemplo)#2 ), ou seja, serão objetos diferentes.

Em alguns casos, duas instâncias de uma mesma classe podem trazer alguns problemas, então é necessário certificar-se também que o objeto não será clonado. Podemos fazer isso da seguinte forma:

---------------------------------
class Exemplo {
public static $instance;

private function Exemplo()
{
}

public static function getInstance()
{
if (!isset(self::$instance)) {
Exemplo::$instance = new Exemplo();
}
return Exemplo::$instance;
}

public function __clone()
{
die('unable to clone... sorry');
}
}
$a = Exemplo::getInstance();
var_dump ( $a );

$a = Exemplo::getInstance();
var_dump ( $a );

$b = clone $a;
var_dump ( $b );
?>
---------------------------------
Executando temos:

---------------------------------
$ php exemplo.php
anmsxobject(Exemplo)#1 (1) {
["nome"]=>
string(5) "anmsx"
}
object(Exemplo)#1 (1) {
["nome"]=>
string(5) "anmsx"
}
unable to clone... sorry
---------------------------------

Assim, quando a primeira instância fosse clonada, o método __clone da classe iria interromper a execução do script e emitir uma mensagem de erro ( sim, bastante grosseiro, mas é apenas a títuloo de ilustração

Há outros macetes ainda, mas o principal foi demonstrado no artigo
.anmsx
23/08/2006 10:32pm (~10 anos atrás)

Marcos Regis disse:
O artigo do Adler é válido e importante para a comunidade PHP que eh carente de profissionais que conhecem alguma metodologia de desenvolvimento.
Quanto a utilidade de tais métodos estou com você Felipe.
Uma vez disse a um outro programador que as vezes usar o formato OO no PHP era perda de desempenho ao invés de ganho. Não preciso nem dizer que fui esculachado.
Trabalho há exatos 11 meses em um sistema que usa muito MySQL e por ter muitos acessos preferi deixar no formato "antiquado" de um include de conexao. Ao verem meu código riram de mim dizendo que estava "defasado" que jah era hora de usar OO. Caí na besteira de uar uma classe que havia feito extremamente abstrata e que depois a extendia para usar com mysql. Resultado, aumento de 7% no tempo de respostas do site.
Não estou bem certo do motivo mas acho que quando vc tem uma classe com muitos métodos o PHP tem que "parsear" todos eles a cada vez que vc dá um include na classe e aumenta o tempo do processamento do script.
Talvez se um dia o PHP gerar binarios a partir da classe e isso mude um pouco.
Quanto aos hosts acredito que a maioria ainda não esteja em PHP5 porque os repositórios das distros ainda não estão com ele.
Das que jah testei, apenas o UBUNTU tinha PHP5.0+MySQL 5.
Nem mesmo o CENTOS 4.3 tem PHP5.
Claro que eh só instalar manualmente que resolve.
15/08/2006 1:35pm (~10 anos atrás)

Até que ponto o singleton é instancia única MESMO em PHP? Eu estava pensando, e como PHP nao tem o conceito de aplicação, cada hit na pagina é uma "thread" independente, e no PHP esse singleton seria único apenas naquela pagina que um usuario ta acessando na hora, estou certo? Se duas pessoas acessam a pagina simultaneamente, o que acontece são dois "processos" independentes que nao acessariam esse mesmo objeto singleton, mas sim dois objetos independentes. Eu me vi com esse problema pois queria fazer o parsing de um xml e colocar num objeto singleton, com php, por questoes de performance para nao fazer esse bendito parsing toda vez que alguem visitasse a página, mas nao consegui justamente por nao ter um singleton que ficasse realmente na memória.
08/08/2006 12:58pm (~10 anos atrás)

Thiago Santos disse:
Fala, eu estava dando uma lida em singleton no php.net e eu não achei muita aplicatividade, já que muita gente programa estruturado em php e em OO vc pode simplesmente instanciar uma classe e usa-la naquele momento.

vc poderia explicar o que seria essa instancia global?

até mais,

Thiago
01/08/2006 11:33am (~10 anos atrás)

Fala galera, criei a FAQ referente ao assunto...
Vamos postar lá os provedores que conhecemos para que possamos todos começara a usar a nova versão do PHP.

Segue o link:
http://phpbrasil.com/phorum/read.php?f=1&i=88217&t=88217

Att,

Wescley Costa - AKA Narixx
24/07/2006 12:57pm (~10 anos atrás)

Newton Wagner disse:
Acho ótima a idéia. A muito tempo atrás tinha um FAQ que eu abri sobre discussões sobre hosts. Apesar de algumas propagandas que rolaram, acho que o desenvolvimento foi legal.

Poderia abrir um FAQ com as hospedagens de PHP 5. Nacional eu só conheço a locaweb (mas é um pouco mais caro tb).
24/07/2006 12:20pm (~10 anos atrás)

Concordo plenamente Adler...
Mas vamos colocar aqui mesmo?
Será que o pessoal do PHP Brasil não vai achar ruim??
Pois querendo ou nao, será uma propaganda né...

Att,

Wescley Costa
24/07/2006 10:38am (~10 anos atrás)

Adler Medrado disse:
Valeu Wescley!

Eu ia falar exatamente isso que o Wescley falou.
Se não tiver demanda de PHP5 os Hosts não irão colocar mesmo. Existem alguns que possuem a gente poderia até fazer uma lista e disponibilizar aqui, o que acham?
[]s

adler medrado
http://adler.neshertech.net
24/07/2006 10:01am (~10 anos atrás)

Newton, realmente existe esse problema... A maioria dos servidores não atualizam para o php5 até pq já possuem várias aplicações rodando em php4 oq poderia acarretar em perda de clientes... O correto seria eles deixarem o servidor rodando o php4 e colocar um novo rodando php5 para os novos projetos... mas... nem todos pensam assim!
Mas o esquema é desenvolver em PHP5, acompanhar a evolução e procurar algum servidor que possa hospedar, pq se for querer acompanhar a maioria dos servidores vc vai acabar ficando para trás...

Att,

Wescley Costa
24/07/2006 9:25am (~10 anos atrás)

Novo Comentário:

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