Back-End

29 mai, 2007

Padrões de Projeto – Singleton

Publicidade

Salve, Salve leitores do iMasters.

Há algum tempo venho recebendo e-mails dos leitores com dúvidas sobre o desenvolvimento em PHP. De como eu faço ou deixo de fazer algo, de qual a melhor forma de fazer isso ou aquilo. E uma curiosidade me chamou a atenção!

Ninguém nunca me perguntou sobre COMO DESENVOLVER UM CÓDIGO DE QUALIDADE COM PHP!!

Pessoal! Não é para rir não! Isso é um assunto sério!

O PHP, a partir da versão 4, aderiu aos conceitos de Programação Orientada a Objetos (POO) trazendo com isso todas as vantagens desse paradigma, como reutilização de código, organização, encapsulamento, entre outras.

Mas não adianta termos em mãos uma linguagem, por mais sofisticada que seja, se não soubermos utilizá-la eficientemente.

Infelizmente, ainda encontro programadores bastante experientes no PHP, que “mandam e desmandam” na codificação, verdadeiros “magos”, mas que em termos de Arquitetura de Software ainda deixam muito a desejar.

Arquitetura de Software?

É isso mesmo! Software também possui uma arquitetura!

Talvez, em um projeto trivial, você não se depare com alguns problemas de estruturação de código, mas a medida que o sistema cresce você acaba se perdendo na sua própria codificação. E o projeto, sem uma boa base, acaba cedendo a seu próprio peso. O Projeto DESMONORA!!

Os profissionais mais experiente já devem ter passado pela seguinte situação:

[i]”Sua empresa foi contratada para desenvolver um sistema de gestão interna em uma empresa. O sistema controla os processos de desenvolvimento do produto, acompanhando o pedido do cliente em todas as etapas do processamento, desde o atendimento até a entrega do material.

Foi escolhida a plataforma WEB pois a empresa possui planos de expansão do sistema para possibilitar o cliente acompanhar seu pedido através da Internet, além de permitir o gestor da empresa acompanhar tudo que se passa nos processos internos da organização através de relatorios.”[/i]

Bem, até aqui está tudo tranquilo. Você desenvolve o sistema, você recebe elogios, seus olhos se enchem de lagrimas e coisa e tal.

Até que…

Um pouco antes de você concluir e entregar o seu trabalho, o seu cliente liga querendo efetuar “algumas” alterações no sistema.

“Estive pensando… Resolvi aumentar a empresa, construirei filiais em outros estados e preciso que você coloque as informações e políticas de acesso individuais por filial mas gostaria dessas informações de uma forma centralizada para meus relatórios.”;

Você ergue as mãos, com um certo desespero e responde:

“Mas senhor, isso não estava previsto! Terei que refazer muita coisa para adotar essa alteração!”

QUE PESSÍMA RESPOSTA você deu hein?

Você encerra a conversa e pensa:

“Onde foi mesmo que eu deixei esse código?”

Em seguida abre um diretório e encontra N arquivos com extensões js, php, gif, jpg, css, xml, html; escolhe um arquivo php e não se recorda o que aquele código faz e nem porque foi feito daquele jeito;

“Por onde eu começo?”

Alguém já passou por isso? (Calma, não precisam levantar as mãos todos de uma vez).

Pessoal, as alterações devem ser aceitas. Elas vão existir em todas as etapas do projeto, até mesmo depois que o sistema é entregue e aceito formalmente. As alterações sempre existirão. E é seu papel se antecipar a essas mudanças!

“E como eu faço isso?”

Existem diversas práticas e disciplinas para AMENIZAR o desespero das alterações, além de implantar um processo de desenvolvimento de software, documentando, especificando, e sobretudo PROJETANDO. Você terá que aderir e investir em habilidades na criação de um código de qualidade. Nasce os Patterns DesignPadrões de Projetos.

Termo criado pelo arquiteto Christopher Alexander em 1977, os Padrões de Projeto descrevem características comuns em designes arquiteturais e explicam como novos designes de projetos podem ser criados a partir da agregação de padrões bem-conhecidos.

Um Padrão de Projeto possui um nome, uma declaração do problema e a solução que descreve a implementação do padrão.

Além disso, os Padrões possuem características comuns quanto aos problemas que são resolvidos, possibilitando a reunião em 3 grupos, chamados também de família: Padrões de Criação, Padrões Estruturais e Padrões Comportamentais.

Começaremos com um padrão simples de implementar da família dos Padrões de Criação – o SINGLETON.

Nome do Padrão: SINGLETON

Problema: Como garantir que UMA e SOMENTE UMA instância de uma certa classe exista durante toda a execução do sistema?

Solução: Na figura 1 podemos ver a solução Singleton com UML.

Figura 1 - Singleton com UMLFigura 1 – Singleton com UML

Ainda está meio abstrato não é mesmo?

Melhoremos! Imagine a seguinte situação:

“Gostaria de criar uma classe que gerasse uma conexão com meu banco de dados. Quando eu acessar a primeira vez essa classe, será construída uma conexão, mas no decorrer da execução, caso exista mais acessos ao banco, gostaria de utilizar a MESMA classe com a MESMA conexão.”

Vamos à implementação com o PHP 5:

class Conexao {
            //Propriedade Estática referenciando um tipo da mesma Classe
            static instancia = false;

          //Construtor Private - Não é possível utilizar new em outras classes
          private function __construct() {
	          //código para criar conexão com banco de dados
          }

          //Metodo para recuperar instancia
          public function getInstancia() {
                 if (!Conexao::instancia) {
                         Conexao::instancia = new Conexao();//chamando construtor
                 }
                 return Conexao::instancia;
           }
}

Vamos por parte…

No PHP 5 existe a definição de classe, certo?

Para instanciar uma classe, ou seja, para criar um objeto de uma classe, precisamos utilizar o operador new.

Exemplo: conexao = new Conexao();

Quando instanciamos uma classe, ao utilizar new, o PHP automaticamente faz a chamada ao método __construct() definido na classe;

Um atributo estático (static) é instaciado somente uma vez e é compartilhado por TODOS os objetos da mesma classe; mesmo que você possua vários objetos de uma mesma classe, esse atributo será o mesmo para todos.

Sabendo desses conceitos, vamos ao nosso código:

Na linha 1 do código definimos a classe Conexao;

Na linha 3 definimos uma atributo de instância estática da classe;

Na linha 5 criamos o método construtor – __construct() – da classe; perceba que o método está marcado como PRIVATE, isso indica que se tentarmos utilizar o operador new com essa classe teremos um erro de execução, EXCETO se utilizarmos internamente à classe;

Na linha 6 colocamos nosso código para executar a conexão com o banco de dados. Esse código ficará dentro do método construtor;

Na linha 11 definimos o método publico getInstacia(). Esse será o único método visível da classe e será responsável por recuperar o objeto instancia;

Na linha 12 executamos o teste condicional, se o atributo instancia for false, ou seja, no primeiro acesso à classe, ele entrará no bloco;

Na linha 13 criamos uma instância da classe Conexao. Perceba que utilizamos o operador new, portanto o método __construct() será chamado, criando uma conexão com o banco de dados.

Mas o método __construct() é private!!

Claro, mas isso não proíbe que a PROPRIA classe acesse esse método. Somente proíbe o acesso do “lado de fora” da classe Conexao;

Na linha 16 retornamos o atributo instancia.

Note pelo código que o objeto instancia será criado apenas UMA vez, note também que, independentemente de onde estamos chamando a classe Conexao, o método getInstancia() retornará SEMPRE o mesmo objeto.

Um outro uso do padrão SINGLETON é quando queremos uma classe de Log para todo o sistema, sem precisarmos utilizar recursos do sistema para instaciar uma classe sempre que precisarmos gravar dados no servidor.

Esse Padrão ECONOMIZA RECURSOS!

Lembro que a utilização dos Padrões de Projeto não é por si só a única maneira de organizar seu código.

Agora MUITO CUIDADO! A utilização dos Padrões de Projetos é uma “faca de dois gumes”. O abuso de Padrões pode “engessar” o projeto, dificultando sua manuntenção.

Próxima semana trago a vocês o Padrão de Projeto Value Object

Abraços e Sucesso!