A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Aula 8 – Padrão Singleton

Apresentações semelhantes


Apresentação em tema: "Aula 8 – Padrão Singleton"— Transcrição da apresentação:

1 Aula 8 – Padrão Singleton
Padrões de Projeto Aula 8 – Padrão Singleton

2 Definição (Abstract Factory)
Fornece uma interface para criar família de objetos relacionados sem especificar suas classes concretas. Quando usar? Quando precisar criar fábricas concretas mas ainda desconhecidas (ex.: fábrica de ingredientes de JP) para criar famílias de produtos concretos mas ainda desconhecidos (ex.: ingredientes como queijo coalho). Tipo de padrão? De criação Como implementar? Padrões de Projeto - Singleton

3 Padrões de Projeto - Singleton

4 Padrão Singleton When ONE is ENOUGH! coisa única
Padrões de Projeto - Singleton

5 Definição O padrão Abstract Singleton garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a ela. Padrões de Projeto - Singleton Hoje começaremos pela definição.

6 When is one enough? Geralmente, quando um recurso global é compartilhado; Aplicações multi-threaded; Aplicações que acessam dados externos banco de dados; impressora; driver de dispositivo; Também é bastante utilizado para logging, caching, pools de threads, preferências e configurações de sistemas, etc. Banco de dados: geralmente é utilizada apenas uma conexão com o banco, porque uma é suficiente, para a maioria das aplicações. Muitas conexões podem tornar a aplicação lenta; Logging: apenas um OutputStream é necessário para “loggar” em um arquivo… Impressão: apenas um spooler de impressão é necessário, não importando a quantidade de clientes que o utilizem… Padrões de Projeto - Singleton

7 Como garantir uma única instância?
Como você criaria um único objeto? E se outro objeto quisesse criar um MyObject? Poderia chamar new em MyObject de novo? Então, se tivermos uma classe, sempre poderemos instanciá-la uma ou mais vezes? E se não for? new MyObject(); Sim, claro. Sim, mas só se for uma classe pública. Se não for pública, apenas as classes do mesmo pacote poderão instanciá-la mais de uma vez. Padrões de Projeto - Singleton

8 Como garantir uma única instância?
Vocês sabiam que isso é possível? O que isto significa? Então, quem poderia usar esse construtor? Por que não? Nunca havíamos pensado a respeito. Mas parece ser possível. Parece ser uma classe que não pode ser instanciada porque o construtor é private. Hmm... Qualquer código dentro de MyClass tem acesso e pode chamar esse construtor privado. Mas isso não faz muito sentido. Porque seria preciso ter uma instância da classe para chamá-lo. Mas como essa primeira instância é criada? public class MyClass{ private MyClass(){} } Padrões de Projeto - Singleton

9 Como garantir uma única instância?
E se MyClass tivesse um método static? Hmmmmmmmm... Assim nós conseguimos usar getInstance e usar o construtor privado para pegar o objeto. public class MyClass{ private MyClass(){} public static MyClass getInstance(){ return new MyClass(); } Padrões de Projeto - Singleton Mas como garantir que somente UMA única instância (singleton) de MyClass seja criada? Hands on!

10 Implementação clássica
Agora chamamos MyClass de Singleton Temos uma variável estática para conter nossa única instância da classe Singleton public class Singleton{ private static Singleton uniqueInstance; //other variables private Singleton(){} public static Singleton getInstance(){ if(uniqueInstance==null) uniqueInstance = new Singleton(); return uniqueInstance; } //other methods Nosso construtor é privado. Apenas Singleton tem acesso a ele. Padrões de Projeto - Singleton Singleton é uma classe normal, e por isso tem outras variáveis que não a que contém a instância de Singleton, bem como também contem outros métodos. Por ser estático, getInstance é a nossa única maneira de conseguirmos uma instância de Singleton. Nele colocamos um código que permite uma única instanciação da classe Singleton.

11 Implementação clássica
Note que essa é a lazyInitialization (instanciação preguiçosa). O objeto só é criado quando alguma classe chama getInstance. Mais adiante veremos outros tipos de inicialização. uniqueInstance contém nossa única instância; lembre-se é uma variável estática public class Singleton{ private static Singleton uniqueInstance; //other variables private Singleton(){} public static Singleton getInstance(){ if(uniqueInstance==null) uniqueInstance = new Singleton(); return uniqueInstance; } //other methods Se uniqueInstance é nulo então é porque ainda não criamos a instância Padrões de Projeto - Singleton E caso não exista, o instanciamos através de seu construtor privado Se uniqueInstance não for nula é porque já foi criada. Então, apenas retornamos uniqueInstance.

12 Padrões de Projeto - Singleton

13 Padrões de Projeto - Singleton
Quando ele fala solteiro, no livro em inglês ele diz single. Traduziram errado. Solteiro, aí, quer dizer único. 

14 Ex.: a Fábrica de Chocolate
Padrões de Projeto - Singleton

15 Ex.: a Fábrica de Chocolate
Padrões de Projeto - Singleton private static ChocolateBoiler uniqueInstance; Constructor: private; public static ChocolateBoiler getInstance(){ if(uniqueInstance==null) uniqueInstance = new ChocolateBoiler(); return uniqueInstance; }

16 Terminologia e Estrutura
getInstance() é static, ou seja, podemos acessá-lo de qualquer outra classe uniqueInstance contém a única instância de Singleton Padrões de Projeto - Singleton Singleton deve ter um construtor private. Lembre-se disto. Uma classe que implementa o padrão Singleton é mais do que um Singleton; é uma classe de fins gerais com seu conjunto de dados e métodos

17 Exemplo com Thread Uma máquina multi-core, executanto o programa da Fábrica de chocolate com duas threads chamando getInstance()… Analise o valor de uniqueInstance ao longo do tempo. Thread 1 Thread 2 public static ChocolateBoiler getInstance(){ if(uniqueInstance==null) uniqueInstance = new ChocolateBoiler(); return uniqueInstance; } Padrões de Projeto - Singleton tempo

18 Problemas com Multithreading
Quando há multithreading o método getInstance() poderia ser chamado mais ou menos no mesmo instante, o que resultaria em mais de uma instância sendo criada; Possíveis soluções: Sincronizar o método getInstance() Utilizar a estratégia de eager initialization ao invés de lazy initialization Usar a trava duplamente verificada para reduzir o uso da sincronização em getInstance() Padrões de Projeto - Singleton

19 Sincronizando getInstance()
public static synchronized ChocolateBoiler getInstance(){ if(uniqueInstance==null) uniqueInstance = new ChocolateBoiler(); return uniqueInstance; } Desvantagem: pode diminuir o desempenho do programa por um fator de 100; Se o desempenho de getInstance não for crítico para o seu aplicativo, essa pode ser uma boa saída. Padrões de Projeto - Singleton Explicar o synchronized explicando que o lock é como se fosse uma chave, e a thread só poderá executar aquele trecho de código quando estiver em posse da chave.

20 ansioso, apressado Eager Initialization public class Singleton{ private static Singleton uniqueInstance = new Singleton(); //other variables private Singleton(){} public static Singleton getInstance(){ return uniqueInstance; } //other methods Padrões de Projeto - Singleton Útil se você sabe que seu programa sempre cria e usa uma instância Singleton. O construtor será chamado na primeira vez que a classe for carregada, ou seja, quando você tentar executar algum método (não necessariamente o getInstance) da classe em questão.

21 Trava duplamente verificada
public class Singleton{ private volatile static Singleton uniqueInstance; //other variables private Singleton(){} public static Singleton getInstance(){ if(uniqueInstance==null){ synchronized(Singleton.class){ if(uniqueInstance==null) uniqueInstance = new Singleton(); } return uniqueInstance; //other methods Garante que várias threads lidem com a variável uniqueInstance corretamente Procure uma instância, e se não houver uma, insira um bloco sincronizado Observe que sincronizamos, apenas na primeira vez (criação). Uma vez no bloco, verifique de novo, e, se ainda for null, crie uma instância. Padrões de Projeto - Singleton Diminui o overhead imposto pela sincronização entre as threads (synchronized)

22 Resumo Permite que exista apenas UMA instância da “classe Singleton”;
Provê um ponto de acesso único e global; É implementado declarando o contrutor private e um método static combinado com uma variável static; É preciso tomar cuidado quando há mais de uma thread criando a instância Singleton. Há três formas de resolver esse problema, cada uma com sua peculiaridade (vantagens e desvantagens): Declarando getInstance() como synchronized; Eager initialization; Trava duplamente verificada. Padrões de Projeto - Singleton

23 Referências [1] O cenário de pizzarias é abordado no capítulo 5 do livro “Padrões de Projeto – Use a Cabeça!” Padrões de Projeto - Singleton


Carregar ppt "Aula 8 – Padrão Singleton"

Apresentações semelhantes


Anúncios Google