Introdução ao Design Pattern Singleton com Delphi

Veja nesta Quick um exemplo prático de Singleton em Delphi.

Olá galera, nesta Quick Tips irei mostrar um dos padrões de projetos mais utilizados hoje em dia no desenvolvimento de Software: o padrão Singleton.

Com o Singleton podemos ter a certeza de que só existirá um único objeto instanciado para determinada classe. Um exemplo seria o usuário conectado ao sistema ou até mesmo a conexão direta ao banco de dados.

Vou criar uma unit e seu nome será uUsuario. Nela implementaremos uma série de configurações dentro de uma classe chamada TUsuario.

Ao criar uma unit vamos declarar a mesma da seguinte forma, e salvar como uUsuario:

unit uUsuario; interface uses uDM, DB, SqlExpr, SysUtils, Dialogs, IdHashMessageDigest; type TUsuario = class Private { Objetivo : Podemos notar que existem fields/variáveis Class Var, estes são necessários que configuremos desta forma, para podermos armazenar o conteúdo do usuário ao ser localizado na base de dados, quando usamos um método de Class, para acessarmos Fields dentro dele, só podemos acessar quando estes são de Class também } class var FID: Integer; class var FSenha: String; class var FNivel: Integer; class var FUsuario: String; class var FInstance: TUsuario; constructor CreatePrivate; constructor Create; { private declarations } protected { protected declarations } public { public declarations } { Objetivo : Efetuar o login a uma base de dados passando usuário e senha, além da conexão ao qual se deseja conectar } class function Login(AUsuario, ASenha: String;xConexao: TSQLConnection): Boolean; { Objetivo : alterar a senha de um usuário logado por exemplo } class function ChangePassword(strOldPassword, trNewPassword,strCheckPassword: String; xConexao : TSQLConnection):Boolean; { Objetivo : Obter a instancia caso exista, ou criar a mesma, apenas uma única vez } class function GetInstance: TUsuario; { Objetivo : Função criada em outro artigo, serve para podermos criptografar uma string utilizando Hash MD5, observe que demos uses em IdHashMessageDigest } class function Criptografar(const Value: string): string; static; { Objetivo : Função para retornar o nome do usuário logado } class function GetUsuarioLogado: String; { Objetivo : Propriedades de configuração da minha tabela de usuário, configure e altere de acordo com a sua necessidade } class property ID: Integer read FID; class property Usuario: String read FUsuario; class property Senha: String read FSenha; class property Nivel: Integer read FNivel; end;

Agora iremos mostrar a implementação dos métodos declarados:

class function TUsuario.Criptografar(const Value: string): string; var xMD5: TIdHashMessageDigest5; begin xMD5 := TIdHashMessageDigest5.Create; try Result := xMD5.HashStringAsHex(Value); finally xMD5.Free; end; end; class function TUsuario.ChangePassword(strOldPassword, strNewPassword, strCheckPassword: String; xConexao : TSQLConnection): Boolean; var xQry : TSQLQuery; begin xQry := TSQLQuery.Create(Nil); xQry.SQLConnection := xConexao; if FSenha = Criptografar(strOldPassword) then begin if strNewPassword = strCheckPassword then begin try xQry.SQL.Add('UPDATE USUARIO SET SENHA = '+QuotedStr(Criptografar(strNewPassword))+ ' WHERE IDUSUARIO = '+ IntToStr(FID)); xQry.ExecSQL; Result := True; FSenha := Criptografar(strNewPassword); MessageDlg('Senha alterada com sucesso !!!!', mtInformation,[mbOK],0); finally FreeAndNil(xQry); end; end else MessageDlg('As senhas não conferem !!!!', mtInformation,[mbOK],0); end else MessageDlg('A senha antiga não confere !!!!', mtInformation,[mbOK],0); end; constructor TUsuario.Create; begin raise Exception.Create('Para obter uma instância de TUsuario utilize TUsuario.GetInstance !'); end; constructor TUsuario.CreatePrivate; begin inherited Create; end; class function TUsuario.GetInstance: TUsuario; begin if not Assigned(FInstance) then FInstance := TUsuario.CreatePrivate; Result := FInstance; end; class function TUsuario.GetUsuarioLogado: String; begin Result := FUsuario; end; class function TUsuario.Login(AUsuario, ASenha: String; xConexao: TSQLConnection): Boolean; var xQry : TSQLQuery; begin try xry := TSQLQuery.Create(Nil); xQry.SQLConnection := xConexao; xQry.SQL.Add('SELECT * FROM USUARIO WHERE DESCRICAO = '+QuotedStr(AUsuario)+ ' AND SENHA = '+QuotedStr(Criptografar(ASenha))); xQry.Open; if not xQry.IsEmpty then begin FID := xQry.Fields[0].AsInteger; FUsuario := xQry.Fields[1].AsString; FSenha := xQry.Fields[2].AsString; FNivel := xQry.Fields[3].AsInteger; Result := True; end else ShowMessage('Usuario ou senha inválidos'); except on E : EXCEPTION do raise Exception.Create('ERRO NAO ESPERADO '+ E.Message +#13+ E.ClassName + ' - - - ' + E.UnitName); end; end; end.

O que é interessante nestes métodos, é que podemos aproveitá-los para outros projetos, montados nesta uUsuario.pas.

Agora irei mostrar como usar os métodos implementados anteriormente na unit uUsuario.pas. Veja como é simples a implementação da mesma.

Fico por aqui ate à próxima Quick Tips.

Artigos relacionados