Design Patterns (ou padrões de projeto) representam as melhores práticas utilizada por desenvolvedores experientes quando se trata de projetos orientados a objetos.
Neste post, veremos o padrão Singleton, listado no livro GoF (Gang of Four).
Singleton
Objetivo
Garantir que uma classe tenha apenas uma instância, e prover um ponto global de acesso a ela.
Motivação
Para determinada situação, é recomendável (ou necessário) que uma classe tenha apenas uma instância para o projeto todo.
A pergunta muitas vezes é: quando eu precisarei ter apenas uma instância global?
Um exemplo: em alguns bancos de dados rodando em modo embarcado (ex: javaDB, H2), estes bancos não suportam multiplas conexões: cada banco de dados permite apenas uma única conexão ativa.
Neste caso, o padrão singleton resolve este problema, garantindo apenas um objeto de conexão ao banco de dados, e um ponto global de acesso a ele.
Estrutura
O método getInstance() deve ser estático, e ser o único ponto de acesso a instância do objeto. O construtor deve ser privado, para evitar que esta classe seja instanciada em outro local.
Consequências
1 – Controle de acesso a instância única
Por prover um ponto único de acesso, pode ser verificado como e quando está sendo acessado
2 – Permite um número variável de instâncias
Se em algum motivo precisar de mais de uma instância, basta alterar no ponto de acesso
3 – Permite refinamento
Classes singleton podem ter subclasses, e é fácil configurar a aplicação para obter uma instância da classe filha. É possível inclusive configurar a instância da classe filha dinamicamente, se for o caso. Novamente, basta alterar no ponto de acesso.
4 – Mais flexibilidade do que operações de classe (métodos estáticos)
As operações de um singleton poderiam ser métodos de classe (estáticos). Mas esta técnica,além de não ter a flexibilidade de poder operar atributos de um objeto, não podem ser sobrescritas polimorficamente.
Exemplo 1
Em java, um Singleton, em sua forma mais simples, pode ser escrito assim:
public class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() { } public static Singleton getInstance() { return INSTANCE; } }
Obs 1: a instância é privada e estática
Obs 2: o construtor é privado
Obs 3: o método getInstance() é estático, e retorna o objeto
A instância pode ser obtida a qualquer momento da seguinte forma:
Singleton instancia = Singleton.getInstance();
Exemplo 2
Para garantir que a instância só vai ser criada quando o singleton for chamado pela primeira vez:
public class Singleton { private static Singleton INSTANCE = null; private Singleton() { } public static Singleton getInstance() { if (INSTANCE == null) { INSTANCE = new Singleton(); } return INSTANCE; } }
Exemplo 3
Poderia-se, inclusive, definir classes especializadas deste Singleton, e variar sua instância única de acordo com alguma variável de ambiente:
public class Singleton { private static Singleton INSTANCE = null; private Singleton() { } public static Singleton getInstance() { if (INSTANCE == null) { //faz referencia a uma variavel de ambiente String so = System.getenv("os.name"); //dependendo da variavel, retorna uma instancia especializada if (so.equals("windows")) { INSTANCE = new SingletonWindows(); } else if (so.equals("linux")) { INSTANCE = new SingletonLinux(); } else { //implementacao padrao INSTANCE = new Singleton(); } } return INSTANCE; } }
Espero ter ajudado.
Um abraço
Referências:
Padrões de Projeto – Soluções Reutilizáveis de Software Orientado a Objetos.
0 Comentários.