Delphi – Criando classe Singleton


Durante o processo de desenvolvimento de um sistema, técnicas e padrões dos mais diversos são adotado até mesmo o POG(Programação Orientada a Gambiarra, rsrs). Neste post será mostrado uma implementação do padrão de projeto Singleton.

Singleton é um padrão de projeto de software (do inglês Design Pattern). Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto.

https://pt.wikipedia.org/wiki/Singleton

No exemplo foi criado uma classe chamada TStatus que possui 3 atributos UsuarioLogado, Terminal, Configuracao. Está classe sugestiona uma instância de um objeto único que mostra o status de algumas informações de um sistema após o usuário efetuar o login, garantindo assim que estas informações estejam sempre de maneira organiza e o melhor em um único lugar. Aplicabilidade deste padrão de projeto é imensa o exemplo é bem suave.

Classe TStatus

unit uStatus;

interface

uses
 uConfiguracoes, classes;

type
 TStatus = class(TPersistent)

 strict private
 //está que será a variável que armazenará a ÚNICA instância do objeto.
 class var FInstancia: TStatus;
 constructor Create();

 private
 FUsuarioLogado: String;
 FConfiguracoes: TConfiguracoes;
 FTerminal: string;

 procedure SetConfiguracoes(const Value: TConfiguracoes);
 procedure SetTerminal(const Value: string);
 procedure SetUsuarioLogado(const Value: String);

 public
 class function GetInstancia():TStatus;

 published
 property UsuarioLogado:String read FUsuarioLogado write SetUsuarioLogado;
 property Terminal:string read FTerminal write SetTerminal;
 property Configuracoes: TConfiguracoes read FConfiguracoes write SetConfiguracoes;

 end;

implementation

{ TStatus }

constructor TStatus.Create;
begin
 FConfiguracoes := TConfiguracoes.Create;

end;

//método responsável por retorna a instância do objeto.
class function TStatus.GetInstancia: TStatus;
begin
 if not Assigned(FInstancia) then
 FInstancia := TStatus.Create;

 Result := FInstancia;
end;

procedure TStatus.SetConfiguracoes(const Value: TConfiguracoes);
begin
 FConfiguracoes := Value;
end;

procedure TStatus.SetTerminal(const Value: string);
begin
 FTerminal := Value;
end;

procedure TStatus.SetUsuarioLogado(const Value: String);
begin
 FUsuarioLogado := Value;
end;

end.

Foi criado uma aplicação para exemplificar o uso. Em um primeiro momento é aberto uma janela de login e senha. Após a validação é guardado o usuário logado e aberto a janela principal do sistema. No momento de guardar o usuário logado é chamado a classe e o método GetInstancia() este método é responsável de retornar sempre a mesma instância da classe.

login

procedure TfrmLogin.btnAcessarClick(Sender: TObject);
begin
 if (txtUsuario.Text.Equals('lucas')) and (txtSenha.Text.Equals('123')) then
 begin
 TStatus.GetInstancia.UsuarioLogado := txtUsuario.Text;

 frmMain := TfrmMain.Create(nil);
 frmMain.ShowModal;
 self.Close;
 end;
end;
Logo em seguida é aberto a janela principal do sistema e mostrado na barra de status o usuário logado.

main

procedure TfrmMain.FormShow(Sender: TObject);
begin
 lblUsuarioLogado.Text := lblUsuarioLogado.Text + ' '+ UpperCase(TStatus.GetInstancia.UsuarioLogado);
end;

O exemplo é muito simples é somente para dar uma ideia de uso deste padrão de projeto. Por exemplo poderia após o usuário efetuar o login carregar as permissões de acesso que o mesmo possui para algumas ações dentro da aplicação, e com isto acessa-las de qualquer parte do sistema e sempre do mesmo lugar. Em uma outra situação poderia acessar configurações do comportamento do sistema para determinadas funcionalidade, tendo a certeza que vai estar no mesmo lugar e organizadamente.

 if TStatus.GetInstancia.Configuracoes.Config1 = 'bla bla' then
 begin
 ...
 end;

 if TStatus.GetInstancia.Configuracoes.Config2 = '123' then
 begin
 ...
 end;

A jogada deste padrão é manter uma única instância do objeto conseguimos isto com a seguinte linha em conjunto com o método abaixo.

.
.
.
strict private
//está que será a variável que armazenará a ÚNICA instância do objeto.
class var FInstancia: TStatus;
.
.
.
class function TStatus.GetInstancia: TStatus;
begin
if not Assigned(FInstancia) then
FInstancia := TStatus.Create;

Result := FInstancia;
end;
.
.
.</pre>
<pre>

 

Leave a comment