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.
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.
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>