quarta-feira, 30 de abril de 2008

Padrões GOF (Padrão Singleton)

Aulas 18 e 19

Quando falamos em java, vem logo a idéia de objetos que são criados a partir de instâncias de classes e de reutilizar essas classes para que sejam criados outros objetos quando não mais for necessários aqueles que estas classes criavam. Pois bem, podemos criar vários objetos a partir de instâncias de uma mesma classe, mas o que vamos ver nesse padrão, é totalmente ao contrário, ou seja, o padrão singleton, sugere que apenas uma instância da classe seja criada e garante que mais ninguém crie outra instância, mas em que casos precisaremos usar apenas uma instância de uma classe? Como disse Metsker em seu livro Padrões de Projeto em java, “é mais fácil explicar como garantir que uma classe só tenha uma instância do que explicar por que nós podemos desejar essa restrição”, mas vamos tentar dar um exemplo para que não fique muito vaga essa idéia do singleton. Em uma aplicação que necessite de um log de dados (termo utilizado para descrever o processo de registro de eventos relevantes num sistema computacional), pode-se implementar uma classe com o padrão singleton, desta forma existe apenas um objeto responsável pelo log em toda a aplicação que é acessível unicamente através da classe singleton.

Segundo Metsker, dispomos de várias maneiras para criar um singleton, todavia, o importante é garantir que outros desenvolvedores não criem novas instâncias da classe que queremos limitar, portanto, vamos à solução:

É de conhecimento comum que, para criar uma instância de uma classe, devemos chamar o seu construtor, normalmente, esses construtores são públicos, muitos desenvolvedores desconhecem, mas é possível criar um construtor privado, assim, a classe só pode ser instanciada dentro de algum dos seus próprios métodos.

Criada a classe com o método privado, agora temos que criar uma variável que armazene a instância dessa classe.

Talvez você esteja se perguntando porque utilizar variável estática, simplesmente porque uma variável estática não perde o seu valor cada vez que ela for instanciada, assim, se a classe singleton for instanciada, o valor da instância permanecerá na variável e quando alguém tentar instanciá-la novamente, um método implementado para essa finalidade retornará aquele valor que já havia nela quando foi instanciada pela primeira vez (essa é a funcionalidade principal de um singleton).

Assim, com o código acima, ao instanciarmos os objetos m1 e m2, será retornado o mesmo valor para os dois.

Mas ainda há um pequeno problema quanto a esse código. Em ambientes multi-threaded, pode ocorrer de duas threads tentarem instanciar o objeto ao mesmo tempo, nesse caso, haverá um problema, provavelmente as duas conseguirão instanciar e serão criados dois objetos, o que fere a mecânica do singleton, uma solução para este problema seria utilizar o atributo syncronized no método getInstance(), este atributo garante a sincronização das threads que tentam instanciar a classe singleton, em outras palavras, garante que outra thread não possa acessar a classe até que a thread que a acessou pela primeira vez tenha terminado de fazê-lo.

O singleton é um dos padrões que não devem ser utilizados frequentemente, pois o uso abusivo de singletons leva a soluções onde a dependência entre objetos é muito forte, além do que, uma situação em que realmente é necessária apenas uma instância de uma classe é difícil.


REFERÊNCIAS


WMagician, Artigo, Padrão Singleton em Java

Macoratti, José Carlos Macoratti, Artigo, O Padrão Singleton

Manual do PHP, Escopo de variáveis

Metsker, Steven John Metsker, Padrões de Projeto em Java

Nenhum comentário: