Design Patters – Singleton

Este post utiliza em seu contexto e exemplos a linguagem de programação C# (CSharp).

O padrão Singleton com certeza é um dos mais conhecidos entre os desenvolvedores. Talvez seja por que ele é relativamente simples, ou, então, por que é muito amado e muito odiado por seus defensores e opositores, respectivamente. Seja como for, é um padrão que tem seu valor e sua utilização dependerá do cenário que você, Arquiteto ou Desenvolvedor, precisa resolver, por isso, não devemos desprezar seu valor.

Singleton, em Inglês, pode ser traduzido como Solteirão, Filho ou Coisa Única. A explicação do pattern começa exatamente por aí.. Em Engenharia de Software, Singleton nada mais é do que uma classe que permite apenas uma única instância.

Deduzo que, por estar lendo este post, você deve ter familiaridade com Programação. Caso nunca tenha visto a implementação de um Singleton, você deve estar se perguntando como é possível para uma Classe garantir que apenas uma instância dela seja criada, uma vez que podemos criar objetos utilizando a palavra reservada new a qualquer momento em nosso código? Esta é uma excelente pergunta para relembrarmos um pouco dos conceitos de Programação Orientada a Objetos. Vejamos:

Existe um método que é invocado automaticamente pelo operador new logo após a memória necessária para armazenar o objeto ser alocada. Esse método é o que chamaos de construtor. É nos construtores que fazemos toda a inicialização das dependências daquele objeto e o preparamo para ser utilizado em nosso sistema. Os construtores se diferenciam de métodos tradicionais por algumas características:

  • Construtores têm obrigatiriamente o mesmo nome da classe (inclusive respeitando a mesma grafia com maiúsculas e minúsculas)
  • Construtores não possuem tipo de retorno

Vejamos um exemplo:


public class Dragon
{
int age;
public Dragon(int dragonAge)
{
age = dragonAge;
}
public bool Dracarys()
{
// Burn all the enemies
return true; //return true because they are all dead
}
}

view raw

Dragon.cs

hosted with ❤ by GitHub

Esse exemplo tem pouca aplicação na vida real (uma pena, por que seria incrível ter um Dragão, rs!) mas serve para o propósito de ilustrar nosso exemplo.

A classe Dragon, do exemplo, e possui um método público com mesmo nome. Assim, sempre que uma instância dessa classe é criada por meio do operador new, o método Dragon(int) será imediatamente chamado após a alocação de memótria.

É possível que você já tenha visto algumas classes que não possuem construtores. Mas como é possível existir uma classe que não possui, se toda vez que instanciamos um objeto o método construtor é invocado automaticamente?

Vamos começar a responder esta perguntanta entendendo que nem toda classe necessariamente precisa ter processamento realizado dentro do construtor. Se no cenário hopotético do exemplo anterior a idade do Dragão não fosse importante, poderíamos elimitar o construtor da classe e ela ficaria parecida com algo assim:


public class Dragon
{
public bool Dracarys()
{
// Burn all the enemies
return true; //return true because they are all dead
}
}

view raw

Dragon.cs

hosted with ❤ by GitHub

Nesse caso, podemos claramente ver que a classe não possui construtor, isto é, um método homônimo (com mesmo nome).

Nesse caso, o compilador entende que não é necessário efetuar nenhum processamento no construtor dessa classe e (grosseiramente falando) “adiciona automaticamente” um construtor padrão por você, isto é, um método sem tipo de retorno e com o mesmo nome da classe.

Ou seja, mesmo que você não tenha especificado, o construtor estará lá. Por isso é possível que classes sem um construtor explícito sejam instanciadas.

Agora voltemos a pergunta inicial, que tentava explicar como uma classe pode garantir que apenas uma instância dela seja criada em todo o ciclo de vida do sistema. A resposta está exatamente nos construtores. Ora, os construtores dos quais falamos até agora são todos públicos, ou seja, eles estão acessíveis para serem invocados pelo operador new.

O que acontece, então, se o construtor for privado?

Se o construtor de uma classe for privado, apenas métodos pertencentes aquela classe poderão acessá-lo, ou seja, o operador new não poderá invocá-lo durante a criação do objeto e, dessa forma, você não poderá instanciar objetos utilizando a sintaxe Dragon viserion = new Dragon(), por exemplo.

Assim, podemos concluir que a criação de instâncias de uma classe que possui apenas construtores privados deve ser feita por ela mesma. E, dessa forma, a classe pode controlar quantas instâncias serão criadas.

[continua]

Encontrou algum erro ou quer sugerir uma melhoria para este post? Entre em contato comigo pelo formulário a seguir.. Críticas construtivas nos ajudam a fazer cade vez melhor o nosso trabalho.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: