MVCBr – Patterns Singleton – Desvendando o Framework #10

Share Button

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 como já vimos antes (ver mais: princípio adaptador para interface ). Como uma classe adaptadora, é possível aplicar o “generics” para retornar o próprio singleton adaptado pela classe, vejamos:

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.

caso 1
Para criar uma instância local da interface – não parece lógico, somente para ilustrar, podemos fazer:

var
  MinhaClasseFactory: IMVCBrSingleton<TMinhaClasseAlvo>;
begin
  /// LOCAL
  /// criando a classe factory para singleton
  MinhaClasseFactory := TMVCBrSingleton<TMinhaClasseAlvo>.New();
  showMessage(MinhaClasseFactory.mudarFlag(true).ToString);
...

caso 2
Usando a classe factory que implementa uma herança de TMVCBrSingleton:

   // usa o singleton 
   showMessage( MinhaClasseFactory.mudarFlag(false).toString);