Class Helper – Adicionando uma nova variável, você já tentou ?

By | setembro 8, 2017
Share Button

Por algum tempo fiquei pensando em uma solução para Class Helper ganhar poder de adicionar uma nova variável. Confesso que já estava desistindo, parecia não ser possível… mas – pensando bem….

Digamos que você tenha uma classe base que gostaria de fazer um Class Helper dela:

Exemplo de uma classe original:

     
     TComponentX = class(TComponent)
      public
      published
     end;

(Code:A)

O desafio é como incluir uma nova variável a classe TComponentX utilizando de Class Helper…

Razões para usar um "Class Helper" e não uma herança: 
    se houver possibilidade de injetar a variável através de herança, 
    é provável que não irá precisar criar um "Class Helper" 
    - as razões para criar um "Class Helper" 
    é dispensar mudanças nos objetos em units já implementadas.

Agora, vamos usar o “Class Helper” para injetar uma nova variável à classe TComponentX:

    TComponentHelper = Class Helper TComponent
      public
         Ligado:Boolean;
    end;

(Code:B)

Se estiver habituado ao uso de Class Helper, já deve ter notado que este exemplo (Code:B) não é compilado no Delphi – reclamando que um “Class Helper” não pode inserir uma nova variável. Não seja apressado, já lembrou que existe um “Class Var” e logo sugere escrever assim: ” class var Ligado:Boolean; “… Se este for o seu caso, não tenho boa notícia – você terá criado uma única referência para a variável, não podendo receber valores diferentes nas várias instâncias que a aplicação desejar manter carregada na memória – ou seja, criou uma simples variável GLOBAL que é compartilhada com todas as instâncias da classe;

No nosso caso, queremos que cada instância tenha o seu próprio valor, portanto não pode utilizar um “Class Var” como solução.

PROPOSTA:

unit Unit1;

interface

uses System.Classes, System.Generics.Collections;

type

  TComponentHelper = Class Helper for TComponent
  protected
    function GetLigado: boolean;
    procedure SetLigado(const AValue: boolean);
  public
    property Ligado: boolean Read GetLigado write SetLigado;
  end;

implementation

var
  LComponentLigado: TDictionary<TComponent, boolean>;

function TComponentHelper.GetLigado: boolean;
begin
  result := true; // responde um padrão, para quando não existir;
  if LComponentLigado.ContainsKey(self) then
    result := LComponentLigado.Items[self]; // pega o valor da lista
end;

procedure TComponentHelper.SetLigado(const AValue: boolean);
begin
  LComponentLigado.AddOrSetValue(self, AValue); // inclui na lista
end;

initialization

LComponentLigado := TDictionary<TComponent, boolean>.Create;

finalization

LComponentLigado.free;

end.

A implementação permite adicionar novas variáveis ao objeto do “Class Helper” sem interferir no funcionamento da classe padrão.

6 thoughts on “Class Helper – Adicionando uma nova variável, você já tentou ?

  1. Alexandro Landmann Fenner

    Na verdade esta implementação esta incompleta..
    Primeiro é necessário retirar do dicionário global os itens adicionados ao mesmo.
    Segundo para que se este modelo seja utilizado em um aplicativo multi-thread é necessário adicionar os controles de acesso.
    Mas no geral é uma boa saída para algo bem específico, não seria uma boa ideia o uso generalizado deste modelo em um sistema..

  2. Jocimar

    Muito bom! Parabéns pela dica… são esses tipos de situações que facilitam nossas vidas de programador. E programadores dispostos a compartilhar conhecimento.

  3. Ivan Cesar

    Muito bem colocado Amarildo.
    Quando saiu essa feature no delphi eu imaginei um mundo maravilhoso, até me deparar com essa limitação, que depois de muitas tentativas de várias formas, todas frustradas, cheguei finalmente nesse recurso, e tenho usado desde então com sucesso.
    Isso fica como dica para quem está querendo o mesmo objetivo, usar como “atalho”.
    Parabéns !!

Comments are closed.