1
Padrão: Singleton
• Tipo - “Creational”
• Objetivo - garantir que uma classe tenha
apenas uma instância
2
Motivação
• é importante para algumas classes ter apenas uma
instância a cada momento
– printer spooler
– conversor A/D em filtro digital
• como garantir que uma classe tem apenas uma instância
e que esta instância é facilmente acessível?
– variável global assegura acessibilidade mas não unicidade
• melhor maneira é assegurar que a classe assegura a
unicidade interceptando as mensagens de criação
3
Aplicabilidade
• uma classe deve ter apenas uma instância e
esta deve ter seu acesso indicado em um
local claro
• quanto esta instância única pode ser
extensível por subclasseamento, sendo que
clientes devem poder usar uma destas
“instâncias estendidas” sem modificar seu
código
4
Estrutura (figura)
5
Colaborações
• Clientes obtém uma instância de Singleton
apenas através da operação instância
6
Conseqüências
• Acesso controlado à instância única
• Redução do espaço de nomes
– evita aumento incontrolável de variáveis globais
• Permite refinamento de operações e
representação
– é fácil criar subclasse e é fácil configurar aplicação para
utilizar instância desta nova subclasse
– escolha da classe pode ser feita em tempo de execução
7
Conseqüências (cont.)
• Permite um número variável de instâncias
– com este padrão é fácil mudar a especificação e permitir mais
de uma instância
– pode-se usar a mesma abordagem para qualquer número finito
determinado de instâncias
• Mais flexível que operações em classes
– outra maneira de implementar a mesma funcionalidade é
utilizar operações de classes (métodos de classe em Smalltalk,
funções Static em C++)
– com ambas as técnicas acima é difícil mudar o “design” para
possibilitar mais de uma instância por classe
– funções estáticas em C++ nunca são virtuais, assim não podem
ser re-definidas
Implementação: assegurando unicidade
– esconder a operação que cria a instância dentro de uma
operação de classe que garante a unicidade
– esta operação tem acesso à variável que armazena a instância
única
– em Smalltalk criamos nova versão de new
new
self error: ‘cannot create new object’
default
SoleInstance isNil ifTrue:[SoleInstance:= super new].
^ SoleInstance.
8
9
Assegurando unicidade: C++
– em C++ podemos definir a função estática instance:
• class Singleton {
• public:
•
static Sigleton* Instance();
• protected:
//função é protegida
•
Singleton();
• private:
•
static Singleton* _instance; //como é ponteiro podemos usar
sub-classe
• };
• Singleton* Singleton::_instance = 0;
• Singleton* Signelton::Instance(){
•
if (_instance == 0) {_instance = new Singleton;}
10
Implementação: subclasses de Singleton
• o problema não é criar a subclasse mas garantir a
unicidade da instância mesmo na presença de subclasses
• variável que guarda a instância única deve passar a ser
inicializada com instância da subclasse
• podemos determinar que instância usar no método
Instance, onde guardamos indicação da subclasse a ser
utilizada em uma “environment variable”
• podemos escolher qual subclasse utilizar deferindo a
implementação de Instance() para as subclasses, e
“linkando” a classe desejada na fase final de montagem do
programa
11
Criando subclasses de Singleton
• utilizar um registro para as possíveis subclasses a
serem utilizadas:
– cada subclasse se registra com um nome pré-definido
nos seus construtores
– a função Instance() é alterada para:
Singleton* Singleton::Instance(){
if (_instance == 0) {
const char* singletonName =
getenv(“SINGLETON”);//usupario fornece este variável
_instance = Lokup(singletonname);
}
return _instance;}
12
Usos conhecidos
• conjunto de mudanças do código na
implementação de Smalltalk-80 da
Parcplace
• metaclasses tem apenas 1 instância
• InterViews utiliza esta padrão para acessar a
instância única das classes Session(define
parâmetros de funcionamento da aplicação)
e WidgetKit (define o “look and feel” das
interfaces)
13
Padrões Relacionados
• vários padrões podem ser implementados
utilizando Singleton, em particular
– Abstract Factory
– Builder
– Prototype
Download

Padrão: Singleton - IME-USP