Clique para saber mais...
  Home     Download     Produtos / Cursos     Revista     Vídeo Aulas     Fórum     Contato   Clique aqui para logar | 10 de Novembro de 2025
  Login

Codinome
Senha
Salvar informações

 Esqueci minha senha
 Novo Cadastro

  Usuários
28 Usuários Online

  Revista ActiveDelphi
 Assine Já!
 Edições
 Sobre a Revista

  Conteúdo
 Apostilas
 Artigos
 Componentes
 Dicas
 News
 Programas / Exemplos
 Vídeo Aulas

  Serviços
 Active News
 Fórum
 Produtos / Cursos

  Outros
 Colunistas
 Contato
 Top 10

  Publicidade

  [Artigos]  [Intermediário] -Use Class/Record Helpers no Delphi
Publicado por rboaro : Domingo, Setembro 22, 2013 - 10:01 GMT-3 (354 leituras)
Comentários comentar   Enviar esta notícia a um amigo Enviar para um amigo   Versão para Impressão Versão para impressão
Diego Garcia Você sabe o que vem a ser um Class Helper?
Class Helper é uma técnica da programação orientada a objetos que tem o intuito de estender as funcionalidades de uma classe, sem que seja necessário utilizar herança e sem que seja necessário alterar a classe original. Imagine o seguinte cenário. Em sua aplicação existe a classe TPessoa, que por algum motivo você não pode alterar a sua implementação, mas, necessita de um determinado método nesta classe, como por exemplo retornar a idade da pessoa a partir de sua data de nascimento.

Em situações normais, seria feito um método CalcularIdade() por exemplo e seria usado da seguinte forma:
{...}
EdtIdade.Text := IntToStr(CalcularIdade(oPessoa.DataNasc));
{...}

Agora imagine se fosse desta forma:

{...}

EdtIdade.Text := oPessoa.Idade.ToString;

{...}

Muito mais claro e limpo. Mas como fazer isso sem ter acesso a implementação da classe TPessoa? Simples, fazendo um Class Helper para a classe TPessoa. Faremos um exemplo bem simples para mostrar o uso prático do recurso. Vamos começar pela interface da classe TPessoa:
type
TPessoa = class
private
FDataNasc: TDate;
public
property DataNasc : TDate read FDataNasc write FDataNasc;
end;

Usaremos somente o campo referente a data de nascimento, pois ele está no foco do nosso exemplo. Agora faremos o nosso Class Helper para a classe TPessoa:

type
TPessoaHelper = class helper for TPessoa
private
function GetIdade: integer;
public
property Idade : integer read GetIdade;
end;

implementation

uses
DateUtils,
System.SysUtils;

{ TPessoaHelper }
function TPessoaHelper.GetIdade: integer;
begin
Result := YearsBetween(Self.DataNasc,Now);
end;

Note que para determinar que uma classe é um class helper de outra é necessário utilizar a diretiva helper e indicar a classe principal com a palavra reservada for. Outro ponto que merece atenção é o fato de que, na classe helper, nós temos acesso a todos os atributos públicos da classe principal a partir da própria instância do helper, por esse motivo que foi possível acessar a propriedade DataNasc.

Pronto, agora a propriedade Idade já está disponível para todos os objetos do tipo TPessoa em units que fizerem referência a unit do class helper (caso o class helper TPessoaHelpertenha sido feito em uma unit diferente da unit da classe TPessoa).

Por exemplo:
uses
unt_pessoa,
unt_pessoa_helper;

procedure TForm1.Button1Click(Sender: TObject);
var
oPessoa : TPessoa;
begin
oPessoa := TPessoa.Create;
try
oPessoa.DataNasc := StrToDate('26/11/1986');
EdtIdade.Text := IntToStr(oPessoa.Idade);
finally
oPessoa.Free;
end;
end;

Mas nosso exemplo ainda não terminou. Note que ainda estou fazendo um type castingexplícito na idade, como resolver isso? Utilizando Record Helper :) . A partir do Delphi XE3, é possível criar helpers para tipos primitivos, como por exemplo o tipo integer. Faremos um record helper para o tipo integer com o simples intuito de converter o inteiro para uma string:

TIntHelper = record helper for integer
public
function ToString():String;
end;

implementation

function TIntHelper.ToString: String;
begin
Result := IntToStr(Self);
end;

Agora sim, nosso exemplo está completo:

procedure TForm1.Button1Click(Sender: TObject);
var
oPessoa : TPessoa;
begin
oPessoa := TPessoa.Create;
try
oPessoa.DataNasc := StrToDate('26/11/1986');
EdtIdade.Text := oPessoa.Idade.ToString;
finally
oPessoa.Free;
end;
end;

Vale lembrar que utilizando o helper TIntHelper que criamos, abrimos margem para substituir a clássica conversão StrToInt para simplesmente utilizar a nossa funçãoToString():

var
iNumero : integer;
sTexto : string;
begin
sTexto := 1.ToString; //sTexto = '1'
iNumero := 2;
sTexto := iNumero.ToString; //sTexto = '2'
end;

Mas antes de sair criando helpers para tipos conhecidos, verifique se o próprio Delphi já não disponibiliza um helper para o mesmo intuito. A unit SysUtils possui uma série de helpers para os tipos mais comumente utilizados. Uma dúvida que sempre aparece quando se começa a utilizar class helpers é com relação a criação de mais de um helper para uma determinada classe. Por exemplo, o seguinte código não funciona da maneira que intuitivamente se espera:

TPessoaHelper = class helper for TPessoa
private
function GetIdade: integer;
public
property Idade : integer read GetIdade;
end;

TPessoaFisicaHelper = class helper for TPessoa //esse passa a ser o Helper "ativo"
public
function isValidCPF():Boolean;
end;

Não ocorre um erro de compilação, porém, a propriedade Idade, não estará mais disponível, pois um helper se sobrepõe ao outro. Para que isso não ocorra, é necessário indicar o class helper antecessor, desta forma:

TPessoaHelper = class helper for TPessoa
private
function GetIdade: integer;
public
property Idade : integer read GetIdade;
end;

TPessoaFisicaHelper = class helper (TPessoaHelper) for TPessoa

public
function isValidCPF():Boolean;
end;

TPessoaJuridicaHelper = class helper (TPessoaFisicaHelper) for TPessoa

public
function isValidCNPJ():Boolean;
end;

Devido a evoluções que a arquitetura do Delphi vem sofrendo, principalmente pelas inovações relacionadas a mobilidade, a própria Embarcadero recomenda que se use classe/record helpers para determinados fins, fazendo com que o seu código esteja protegido de eventuais mudanças mais trágicas, como por exemplo a promessa de extinção da concatenação de strings através do simbolo de adição (Ex: Str1 := ‘Texto ‘ + IntToStr(3));


Diego Garcia
http://drgarcia1986.wordpress.com
http://twitter.com/drgarcia1986
https://github.com/drgarcia1986


Comentários Comentários
   Ordem:  
Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos.
  Edição 112

Revista ActiveDelphi

  50 Programas Fontes


  Produtos

Conheça Nossos Produtos

Copyright© 2001-2016 – Active Delphi – Todos os direitos reservados