Singleton – este é um cara engraçado. Não aceita sobrecarga nem substituição – fecha em sí e não abre para estender seu recursos. Maaasss… ele é o fino em compartilhar os seus atributos. Sempre que alguém pergunta por ele, a resposta é a sempre a mesma – inflexível e sem surpresas.
base
Singleton é uma instância global a ser evitada, mas quando não tem outra saída – é um bom parceiro.
elementar meu caro
Sendo um Singleton uma instância global, basta criar a instância uma única vez e sair usando – controlar o momento em que um Singleton pode ser liberado da memória pode ser um bom desafio. Em geral a instância é criado em algum momento do código e sua liberação ocorrerá ao finalizar a aplicação, mantendo-o carregado na memória durante o tempo de vida do aplicativo.
quando usar
Sempre que for necessário uma instância que faça controle de outras instâncias, o Singleton será bem útil. O Delphi possui alguns deles como exemplo o “Application”, uma instância que existe por toda a vida ativa do aplicativo, criado ao entrar e liberado somente quando é encerrado.
O MVCBr possui um subtitulo ao “application” o “ApplicationController”. ApplicationController é uma instância única que mantém uma pilha de “controllers” aberto no aplicativo, aqueles que estão instanciados.
limitações
Quando o desejo é atribuir um variável única para o um objeto específico e suas herança, o uso do Singleton é bastante “simples” – basca criar um “Class Var” para a instância a controlar.
Se de outro lado, se o desejo for permitir herança e cada herança tem o seu próprio Singleton então “Class Var”* não irá resolver a classe base precisa implementar mecanismos mais espertos (*a class var pertencerá sempre ao pai e não permite nova cópia aos filhos).
curiosidades
O TMVCBrSingleton faz uso de outros dois patterns:
LazyLoad – quando cria a instância para a classe alvo somente quando ela for necessária (ver invoke);
Adpater – exporta a classe base por default sem necessidade de fazer referências indiretas ( ver ..factory.mudarFlag(true) .. )
Uma classe que permite transferir um Singleton individual aos filhos
Unit: MVCBr.Patterns.Singleton
O Singleton do MVCBr implementa uma interface de adaptadora para a interface IMVCBrSingleton
[code]
unit singleton.MinhaClasse;
interface
uses MVCBr.Patterns.singleton;
type
/// minha classe alvo
TMinhaClasseAlvo = class(TObject)
public
function mudarFlag(AValue: Boolean): Integer;
end;
/// criando uma classe factory filha
TMinhaClasseFactory = class(TMVCBrSingleton<TMinhaClasseAlvo>)
end;
var
MinhaClasseFactory: IMVCBrSingleton<TMinhaClasseAlvo>;
implementation
{ TMinhaClasseAlvo }
function TMinhaClasseAlvo.mudarFlag(AValue: Boolean): Integer;
begin
result := ord(AValue);
end;
initialization
MinhaClasseFactory := TMinhaClasseFactory.new() ;
end.
[/code]
caso 1
Para criar uma instância local da interface – não parece lógico, somente para ilustrar, podemos fazer:
[code]
var
MinhaClasseFactory: IMVCBrSingleton<TMinhaClasseAlvo>;
begin
/// LOCAL
/// criando a classe factory para singleton
MinhaClasseFactory := TMVCBrSingleton<TMinhaClasseAlvo>.New();
showMessage(MinhaClasseFactory.mudarFlag(true).ToString);
…
[/code]
caso 2
Usando a classe factory que implementa uma herança de TMVCBrSingleton:
[code]
// usa o singleton
showMessage( MinhaClasseFactory.mudarFlag(false).toString);
[/code]