Motivação

Durante o desenvolvimento de aplicações Delphi é comum a necessidade de adicionar aos componentes visuais algumas funcionalidades extras, como validação e formatação de dados. Para atender a esse tipo de situação, alguns programadores optam por utilizar herança, enquanto outros alteram diretamente o código fonte do componente. Essas, porém, não são as melhores soluções, pois a herança obriga a utilização de uma nova classe, ao invés do componente padrão, e a alteração do código fonte pode gerar problemas em outras partes do sistema que utilizem esse mesmo componente.

A fim de suprir essa demanda, a partir da versão 2006 o Delphi passou a contar com um recurso chamado Class Helper, tornando possível adicionar novos comportamentos aos componentes sem usar herança ou modificar o código fonte original.

img Saiba mais sobre a série de cursos sobre Delphi

Definição

No Delphi, Class Helper é um recurso que permite adicionar métodos e modificar comportamentos de componentes em tempo de execução, sem a necessidade de herdar a classe ou utilizar recursos de composição, fazendo parecer que a classe contém o novo comportamento desde sua criação.

Outro diferencial é que Class Helpers não se aplicam somente a componentes. Eles também permitem modificar classes de domínio criadas pelo desenvolvedor, adicionar métodos a estruturas do tipo record e tipos primitivos (introduzidos a partir da versão XE3). Nesse último caso, no entanto, não é possível adicionar propriedades.

Como criar

Na Listagem 1 é apresentada uma unit que implementa um Class Helper para adicionar ao componente TEdit a capacidade de validar seu texto, definindo se ele representa um CPF ou CNPJ.

01	unit UnitEditDocumento;
02
03	interface
04
05	uses
06	   vcl.stdCtrls, SysUtils;
07
08	type
09	   TEditDocumento = class helper for TEdit
10	   private
11	      function TextoSemSinais: string;
12	   public
13	      function isPessoaFisica: boolean;
14	      function isPessoaJuridica: boolean;
15	end;
16
17	implementation
18
19	uses
20	   UnitUtils;
21
22	{ TEditDocumento }
23
24	function TEditDocumento.TextoSemSinais: string;
25	var
26    //Retorna o texto sem caracteres especiais
27	end;
28
29	function TEditDocumento.isPessoaFisica: boolean;
30	begin
31	   result := length(TextoSemSinais) = 11;
32	end;
33
34	function TEditDocumento.isPessoaJuridica: boolean;
35	begin
36	   result := length(TextoSemSinais) = 14;
37	end;
38  end
Listagem 1. Class Helper para um TEdit agregar métodos de validação

Linha 9: sintaxe para declaração do Class Helper. Essa instrução indica que está sendo criado um Class Helper (que é uma classe) para modificar o componente TEdit;

Linhas 10 a 15: declaração dos métodos da classe;

Linhas 24 a 37: implementação dos métodos da classe.

Perceba que toda a estrutura do Class Helper é a mesma de uma classe convencional, alterando apenas a forma de declaração.

Como utilizar

Sempre que for necessário utilizar um componente que possua o novo comportamento, basta adicionar o nome da unit em que está declarado o Class Helper na seção uses. A partir disso, será possível acessar os novos métodos adicionados, conforme mostra a Listagem 2.

01	procedure TForm5.Edit1Exit(Sender: TObject);
02	begin
03	   if Edit1.isPessoaFisica then
04	      Label1.Caption:='Documento Pessoa Física'
05	   else
06	   begin
07	      if Edit1.isPessoaJuridica then
08	         Label1.Caption:='Documento Pessoa Jurídica'
09	      else
10	      begin
11	         Label2.Caption:='Documento Inválido';
12	         exit;
13	      end;
14	   end;
15	end;
Listagem 2. Utilizando os métodos adicionados pelo Class Helper

Nesse código, estamos trabalhando com o evento OnExit do componente TEdit, e nas linhas 3 e 7 utilizamos os novos métodos adicionados pelo Class Helper.

Modificando métodos existentes

Além de adicionar novos métodos, o Class Helper permite que modifiquemos os métodos já existentes em um componente. Na Listagem 3 apresentamos um exemplo de modificação do método Clear para uma situação especial em um formulário onde os componentes TEdit que aceitam texto recebem a string “xxxx” ao serem limpos, e os que aceitam apenas números recebem o texto “0000”. Esse comportamento pode ser necessário em algumas telas do sistema, a partir das quais temos, por exemplo, que imprimir o conteúdo em impressoras matriciais. Nesses casos, em planilhas de formulário contínuo, os campos não podem aparecer em branco para não descaracterizar a impressão.

01	Unit UnitEditMatricial;
02	...
03	type
04	   TEditDocumento = class helper for TEdit
05	   public
06	      procedure Clear;
07	   end;
08
09	...
10
11	procedure TEditDocumento.Clear;
12	begin
13	   if NumbersOnly then
14	      Text:= StringOfChar('0',MaxLength)
15	   else
16	      Text:=StringOfChar('X',MaxLength);
17	end;
Listagem 3. Class Helper para modificar um método já existente no TEdit

Agora, quando adicionarmos a referência a essa unit na seção uses e acionarmos o método Clear de um TEdit, esse novo método será executado, ao invés do procedimento padrão que elimina todo o texto do campo.

Motivação

Durante o desenvolvimento de aplicações Delphi é comum a necessidade de adicionar aos componentes visuais algumas funcionalidades extras, como validação e formatação de dados. Para atender a esse tipo de situação, alguns programadores optam por utilizar herança, enquanto outros alteram diretamente o código fonte do componente. Essas, porém, não são as melhores soluções, pois a herança obriga a utilização de uma nova classe, ao invés do componente padrão, e a alteração do código fonte pode gerar problemas em outras partes do sistema que utilizem esse mesmo componente.

A fim de suprir essa demanda, a partir da versão 2006 o Delphi passou a contar com um recurso chamado Class Helper, tornando possível adicionar novos comportamentos aos componentes sem usar herança ou modificar o código fonte original.

img Saiba mais sobre a série de cursos sobre Delphi

Definição

No Delphi, Class Helper é um recurso que permite adicionar métodos e modificar comportamentos de componentes em tempo de execução, sem a necessidade de herdar a classe ou utilizar recursos de composição, fazendo parecer que a classe contém o novo comportamento desde sua criação.

Outro diferencial é que Class Helpers não se aplicam somente a componentes. Eles também permitem modificar classes de domínio criadas pelo desenvolvedor, adicionar métodos a estruturas do tipo record e tipos primitivos (introduzidos a partir da versão XE3). Nesse último caso, no entanto, não é possível adicionar propriedades.

Como criar

Na Listagem 1 é apresentada uma unit que implementa um Class Helper para adicionar ao componente TEdit a capacidade de validar seu texto, definindo se ele representa um CPF ou CNPJ.

01	unit UnitEditDocumento;
02
03	interface
04
05	uses
06	   vcl.stdCtrls, SysUtils;
07
08	type
09	   TEditDocumento = class helper for TEdit
10	   private
11	      function TextoSemSinais: string;
12	   public
13	      function isPessoaFisica: boolean;
14	      function isPessoaJuridica: boolean;
15	end;
16
17	implementation
18
19	uses
20	   UnitUtils;
21
22	{ TEditDocumento }
23
24	function TEditDocumento.TextoSemSinais: string;
25	var
26    //Retorna o texto sem caracteres especiais
27	end;
28
29	function TEditDocumento.isPessoaFisica: boolean;
30	begin
31	   result := length(TextoSemSinais) = 11;
32	end;
33
34	function TEditDocumento.isPessoaJuridica: boolean;
35	begin
36	   result := length(TextoSemSinais) = 14;
37	end;
38  end
Listagem 1. Class Helper para um TEdit agregar métodos de validação

Linha 9: sintaxe para declaração do Class Helper. Essa instrução indica que está sendo criado um Class Helper (que é uma classe) para modificar o componente TEdit;

Linhas 10 a 15: declaração dos métodos da classe;

Linhas 24 a 37: implementação dos métodos da classe.

Perceba que toda a estrutura do Class Helper é a mesma de uma classe convencional, alterando apenas a forma de declaração.

Como utilizar

Sempre que for necessário utilizar um componente que possua o novo comportamento, basta adicionar o nome da unit em que está declarado o Class Helper na seção uses. A partir disso, será possível acessar os novos métodos adicionados, conforme mostra a Listagem 2.

01	procedure TForm5.Edit1Exit(Sender: TObject);
02	begin
03	   if Edit1.isPessoaFisica then
04	      Label1.Caption:='Documento Pessoa Física'
05	   else
06	   begin
07	      if Edit1.isPessoaJuridica then
08	         Label1.Caption:='Documento Pessoa Jurídica'
09	      else
10	      begin
11	         Label2.Caption:='Documento Inválido';
12	         exit;
13	      end;
14	   end;
15	end;
Listagem 2. Utilizando os métodos adicionados pelo Class Helper

Nesse código, estamos trabalhando com o evento OnExit do componente TEdit, e nas linhas 3 e 7 utilizamos os novos métodos adicionados pelo Class Helper.

Modificando métodos existentes

Além de adicionar novos métodos, o Class Helper permite que modifiquemos os métodos já existentes em um componente. Na Listagem 3 apresentamos um exemplo de modificação do método Clear para uma situação especial em um formulário onde os componentes TEdit que aceitam texto recebem a string “xxxx” ao serem limpos, e os que aceitam apenas números recebem o texto “0000”. Esse comportamento pode ser necessário em algumas telas do sistema, a partir das quais temos, por exemplo, que imprimir o conteúdo em impressoras matriciais. Nesses casos, em planilhas de formulário contínuo, os campos não podem aparecer em branco para não descaracterizar a impressão.

01	Unit UnitEditMatricial;
02	...
03	type
04	   TEditDocumento = class helper for TEdit
05	   public
06	      procedure Clear;
07	   end;
08
09	...
10
11	procedure TEditDocumento.Clear;
12	begin
13	   if NumbersOnly then
14	      Text:= StringOfChar('0',MaxLength)
15	   else
16	      Text:=StringOfChar('X',MaxLength);
17	end;
Listagem 3. Class Helper para modificar um método já existente no TEdit

Agora, quando adicionarmos a referência a essa unit na seção uses e acionarmos o método Clear de um TEdit, esse novo método será executado, ao invés do procedimento padrão que elimina todo o texto do campo.