Boas Práticas, Fundamentos, Técnicas

Design Patterns – Singleton

Olá Pessoal,

No mundo da O.O. uma das  práticas que podemos aplicar em diversos cenários são os Design patterns (ou Padrões de Projeto), que por sinal são modos de resolver problemas recorrentes e que garantem boa reutilização e também expressam de uma forma elegante a resolução de um determinado problema.

Os Design Patterns são classificados em:

  • Padrões de Criação;
  • Padrões  de Estruturas e
  • Padrões de Comportamento.

Cada uma dessas classificações acima englobam diversos tipos de padrões. Nesse post abordaremos o Design Patterns chamado Singleton. Esse Pattern é caracterizado por permitir apenas uma instância de um objeto no sistema e fornecer um ponto de acesso a essa instância, sendo caracterizado como um padrão de criação.

Existem contextos em que poderá haver a necessidade de ter esse tipo de implementação. Por exemplo com classes que possuem dados sobre o sistema, sobre um determinado dispositivo. Imagine que você esta trabalhando em uma aplicação mobile e precisa capturar algum dado do aparelho, ou atualizar determinada informação. Outro exemplo seria configurações de um aplicativo que poderiam ser solicitadas em determinados momentos da execução. Diversos são os cenários que podemos aplicar essa técnica.

O padrão Singleton também é alvo de várias discussões, alguns acham que não há necessidade de utilizar dessa forma, outros preferem combinar padrão Factory, pois poderá limitar a herança e/ou polimorfismo. Enfim, essa é uma discussão para outro momento.

Para transformar uma classe em Singleton existem 3 modificações a serem feitas na classe.

1 – Criar uma instância privada e estática dessa classe;

2 – Criar um método que seja o ponto de acesso ao único objeto criado e

3 – Tornar o construtor padrão privado.

Abaixo temos uma classe chamada Dispositivo bem simples, vamos transformá-la num Singleton. A classe possui dois atributos (Marca e Modelo) e dois métodos chamados Ligar e Desligar além da sobrecarga do método ToString Conforme figura 1.

Singleton1Figura 1 – Classe Comum de Um Dispositivo

Com a nossa classe comum, vamos fazer as três alterações citadas acima para transformá-la num Singleton. As alterações podem ser acompanhadas na figura 2.

Singleton2

Figura 2 – Classe com as alterações necessárias para atender o padrão Singleton.

A partir desse momento, a forma de utilização dessa classe deixa de ser como já conhecemos, não podemos mais instanciar um objeto dessa classe usando o operador new, isso é feito internamente pelo método getInstance que passa a ser o nosso ponto de acesso ao objeto da classe Dispositivo. Na figura 3 podemos ver como deverá ser utilizada.

Singleton3Figura 3 – Exemplo de uso

Essa é a forma que deverá ser utilizada. O método getInstance, verifica se há alguma instância já criada, caso não haja, será criada uma nova instância senão, ele retornará a instância já existente. A Figura 4 mostra o exemplo em funcionamento.

Singleton4

Figura 4 – Exemplo em execução

Bom, essa é uma forma de tratar um tipo de situação num determinado contexto, porém isso exige cuidado na aplicação ou seja, quando aprendemos sobre Design Patterns, costumamos contrair uma doença chamada “Patternite” onde queremos aplicar sempre, seja qual for o pattern. Porém o ideal é deixar que a plicação “peça” o padrão mais adequado, o desenvolvedor perceberá que aquela situação será bem tratada se for aplicado o pattern X.

Quanto ao Singleton, existe um detalhe que será comentado num próximo post, ele não é thread safe, ou seja se mais de uma thread solicitar esse objeto, teremos problemas, e existem formas de contornar essa situação que serão vistas em breve!

Abraço!

Padrão