Padrão de projeto – parte 3: Singleton

Design Pattern: Singleton

Definição segundo GoF:  Garantir que uma classe só tenha uma única instância, e prover um ponto de acesso global a ela.

Exemplo baseado no mundo real: Se você tem um objeto que é uma montadora de carros onde sua responsabilidade é criar vários objetos carros. Existe a necessidade de criar a instância de uma nova montadora a cada vez que for criar um novo carro? A resposta é simples: iniciamos o sistema, criamos uma única instância da montadora, quando necessário (isto chama-se instancialização preguiçosa), e usamos ela para criar todos os carros necessários.

Peraí?! Isto não é a mesma coisa que criar uma variável global e utilizá-la? Não! O singleton é usado justamente para não ter as famosas variáveis globais. Ao invés de ficar criando variáveis estáticas pelo sistema, acessando de tudo que é forma, criamos uma classe, garantimos que só vai existir uma única instância dela em memória e criamos um único ponto de acesso para pegar sua instância.

Aplicações:

  • Um objeto único de acesso a banco de dados;
  • Um objeto único de acesso a um arquivo de log;
  • Um objeto único de acesso a configurações gerais do sistema;
  • Um objeto único que representa um vídeo usado inúmeras vezes no sistema;
  • Uma objeto facade (fachada) único. Este é um pattern que será visto mais adiante.

Vantagens:

  • Não ter variáveis globais sendo acessadas dentro do software;
  • Ter sempre um único local responsável por uma informação estática (instância da classe) (static);
  • Organizar a modelagem e codificação em classes;

Desvantagens:

  • Qualidade da implementação depende da linguagem;
  • Não é tão simples controlar em ambiente distribuído;

Observações: Cuidado na implementação multi-thread. Veja os exemplos de códigos abaixo.

Diagrama de classe:

Fonte: Livro "Use a cabeça!: Padrões de projetos"

Implementação em C#:

public class Singleton
{
    private static Singleton uniqueInstance;
    //-- Outras variáveis de instância úteis aqui

    private Singleton() { } //-- Não pode ser instanciado

    public static Singleton GetInstance()
    {
        if (uniqueInstance == null)
            uniqueInstance = new Singleton();
        return uniqueInstance;
    }

    //-- Outros métodos úteis aqui
}

Close no código:

Fonte: Livro "Use a cabeça!: Padrões de projetos"

Implementação comum em C# thread-safe (multi-threads) sem instancialização preguiçosa:

public class Singleton
{
    private static Singleton uniqueInstance = new Singleton();
    //-- Outras variáveis de instância úteis aqui

    private Singleton() { } //-- Não pode ser instanciado

    public static  Singleton GetInstance()
    {
        return uniqueInstance;
    }

    //-- Outros métodos úteis aqui
}

Implementação em C# thread-safe (multi-threads) com instancialização preguiçosa, variável volatile e lock:

public class Singleton
{
    private static object sync = new object();
    private static volatile Singleton uniqueInstance;
    //-- Outras variáveis de instância úteis aqui

    private Singleton() { } //-- Não pode ser instanciado

    public static Singleton GetInstance()
    {
        if (uniqueInstance == null)
        {
            lock (sync)
            {
                if (uniqueInstance == null)
                    uniqueInstance = new Singleton();
            }
        }
        return uniqueInstance;
    }

    //-- Outros métodos úteis aqui
}

Com o modificador volatile você garante que, independente do processo que esteja acessando a váriavel/propriedade, ele pegará o valor atual da váriavel/propriedade. Um post sobre modificadores virá mais a frente.

Chamada da classe Singleton em C#:

     Singleton sing = Singleton.GetInstance();

Os exemplos em C# são apenas demonstrativos, se alguêm quiser enviar exemplos em outras linguagens eu altero o post e coloco o respectivo nome do autor ;) .

Abrs a todos e até a próxima.

Em questões de estilo, nade contra corrente; em questões de princípios, fique firme como uma rocha.” Thomas Jefferson

2 Responses to “Padrão de projeto – parte 3: Singleton”

  • Vianney says:

    Olá lorival,

    eu não entendi exatamente porque vc declarol um atributo do tipo Object e bloqueou ele no método getInstance.

    Eu pensei que deveria usar o lock(this) para bloquear a fachada?

    Poderia explicar isso melhor.

    Obrigado!

  • lorival says:

    Olá,
    Tudo bem? Peço desculpas por não ter respondido antes seu comentário… tenho que fazer a faxina por aqui, tá muito abandonado.

    O lock você pode aplicar a instância da classe que você está [ é o que o lock(this) faz ] ou aqualquer outro objeto [ que seja criado por referência, ou seja, não vale int, decimal....].

    No exemplo do post, criamos um objeto genérico [ chamado sync do tipo object para ser genérico ] que serve como um semáforo [ podes ver mais sobre isto dentro de Sistemas Operacionais ], onde bloqueamos apenas o acesso a aquele objeto [ quando necessário, naquele caso na criação ]. Ao utilizar o lock(this) estariamos bloqueando toda instância da objeto representado pela classe.

    Assim, com threads concorrentes, criamos um semáforo [ sync ] e definimos como vermelho [ lock(sync) ], ninguém passa enquanto o semáforo [ sync ] estiver bloqueado e assim podemos criar a instância do objeto singleton sem problemas e a instância da classe está livre para ser utilizada por qualquer outro método se necessário.

    Abrs,

Leave a Reply

Desenvolvedor de software, amante pela tecnologia, empreendedor, eclético em sistemas operacionais, analista de sistemas, entusiasta em inteligência artificial, absurdamente ocupado, arquiteto de software , está sempre envolvido em projetos, consultor , adora ir em eventos de tecnologia e empreendedorismo. Desenvolve para PC e Web. Iniciou uma nova jornada de desenvolvimento e estudos em Android e IOS.
Calendário
May 2010
M T W T F S S
« Apr   Jun »
 12
3456789
10111213141516
17181920212223
24252627282930
31  
Nuvem de tags
Total de visitas até ontem
@lorivalsc

Posting tweet...

Powered by Twitter Tools

Biblioteca
Shelfari: Book reviews on your book blog