Post: Eventos e Delegações

Alessandro Medeiros

Fala ai Radizeiros e Radizeiras, tudo bem com vocês?

Neste post irei continuar falando sobre eventos, caso você ainda não tenha visto, aqui no blog tem alguns posts que falo sobre eventos no Delphi.

Se você está interessado e acha que eventos é algo muito legal, te digo, isso não devia ser novo para você, porque uns dos conceitos principais e primordiais para o funcionamento dos componentes no Delphi são os eventos.

Qualquer componente que colocamos no formulário dentro do nosso projeto, como por exemplo o TButton, se observarmos no Object Inspector temos uma propriedade chamada eventos, e todos os eventos foram criados semelhantes aos que criamos em posts anteriores.

Vamos ver um exemplo, em nossa classe TPessoa, onde iremos criar um evento chamado TNotifyEvent, semelhante ao do botão, e criaremos uma property chamada OnCadastro do tipo TNotifyEvent.


type

TNotifyEvent = procedure(Sender : TObject) of Object;

...

property OnCadastro : TNotifyEvent read FOnClick write SetOnClick;

Dentro do método Cadastrar dessa nossa classe chamamos esse evento passando Self, passamos simplesmente o objeto atual.


...

procedure TPessoa.Cadastrar;
var
    Lista : TStringList;
begin
    Lista := TStringList.Create;
    try
        Lista.Add('Nome:' + Nome);
        Lista.Add('Telefone:' + Telefone);
        Lista.Add('Endereço:' + Endereco);
        Lista.Add('Cidade:' + Cidade);
        Lista.Add('UF:' + UF);
        Lista.SaveToFile(Nome + '_Cliente.txt');
        Conexao.Gravar;
        OnCadastro(Self);
    finally
        Lista.Free;
    end;
end;

...

Agora em nossa classe principal iremos criar um método chamado OnCadastro, e no inicio de cada evento iremos chamar esse nosso evento.


...
private
...
procedure OnCadastro(Sender : TObject);
...
procedure TForm1.Button1Click(Sender: TObject);
var
    Cliente : TCliente;
begin
    Cliente := TCliente.Create(TConexaoMySQL.Create);
    try
        Cliente.OnCadastro := OnCadastro;
    ...
end;
...
procedure TForm1.Button2Click(Sender: TObject);
var
    Fornecedor : TFornecedor;
begin
    Fornecedor := TFornecedor.Create(TConexaoMySQL.Create);
    try
        Fornecedor.OnCadastro := OnCadastro;
    ...
end;

Dentro desse nosso evento iremos passar para o memo que encontra-se no formulário o retorno da propriedade Nome da classe TPessoa.


procedure TForm1.OnCadastro(Sender: TObject);
begin
    Memo1.Lines.Add('Foi Cadastrado ' + TPessoa(Sender).Nome);
end;

Neste ponto eu deleguei toda a responsabilidade para minha classe principal, para que esta chame essa função que está tratando esse evento.

Isso é muito semelhante no que fazemos no TButton, onde ele retorna o clique do button.


procedure TForm1.Button5Click(Sender: TObject);
begin
    FormPadrao1.Show;
end;

Agora ao executarmos nosso projeto, e independente da ação ele irá mostrar a informação que definimos dentro do nosso evento.

Agora, o que temos que ter atenção ao trabalharmos com eventos?

Eu poderia em algum momento na hora de chamar o método, esquecer de atribuir o evento para minha classe, como por exemplo no código abaixo, que em vez de declarar o Cliente.OnCadastro := OnCadastro, eu esqueça de colocar.


procedure TForm1.Button1Click(Sender: TObject);
var
    Cliente : TCliente;
begin
    Cliente := TCliente.Create(TConexaoMySQL.Create);
    try
        Cliente.Nome := 'Fulano';
        Cliente.Telefone := '276317263';
        Cliente.Endereco := 'Rua do Teste de Software';
        Cliente.Cidade := 'Niteroi';
        Cliente.Saldo := 1000;
        Cliente.Cadastrar;
        Cliente.CriarFinanceiro;
    finally
        Cliente.Free;
    end;
end;

Sempre que trabalhamos com eventos devemos ter bastante cuidado, eu particularmente não gosto de trabalhar com ele diretamente na propriedade, neste caso eu criaria um método que trate se o evento foi chamado.


...
public
...
procedure EvOnCadastro;
...
procedure TPessoa.EvOnCadastro;
begin
    if Assigned(OnCadastro) then
        OnCadastro(Self);
end;

Como você pode ver, nesse meu método eu verifico se foi atribuído o OnCadastro, ai eu passo o valor para ele, não jogo direto na propriedade.

Dessa forma, onde eu atribuo diretamente, altero e chamo esse meu método.


...

procedure TPessoa.Cadastrar;
var
    Lista : TStringList;
begin
    Lista := TStringList.Create;
    try
        Lista.Add('Nome:' + Nome);
        Lista.Add('Telefone:' + Telefone);
        Lista.Add('Endereço:' + Endereco);
        Lista.Add('Cidade:' + Cidade);
        Lista.Add('UF:' + UF);
        Lista.SaveToFile(Nome + '_Cliente.txt');
        Conexao.Gravar;
        EvOnCadastro;
    finally
        Lista.Free;
    end;
end;

...

Esta é uma forma de validarmos para não dar nenhum erro, caso não tenha sido atribuído.

Se não trabalharmos desta forma e colocarmos diretamente como estava anteriormente, esquecendo de chamar ele em nossa classe, observe o erro que irá dar.

Observe que na hora que cliquei no botão para cadastrar o cliente ele me retornou um erro, isso acontece porque eu não estou tratando isso dentro da classe, então preste bastante atenção nisso.

Cada classe é responsável por tratar todos os seus atributos, todos os seus método, ela não pode delegar esse tratamento para outras classe, para outros objetos de fora, ela não poderia ficar refém de quem chamou a classe Cliente sempre instanciar os eventos, se não pode dar erro.

Não posso deixar isso a cargo de quem chamou a classe, a minha classe tem que se resolver, então se ninguém chamou eu simplesmente ignoro, como fizemos no método EvOnCadastro.

Desta forma se tratarmos dentro da nossa classe Cliente, e esquecermos de chamar nosso evento na classe principal, veja o que acontece.

Observe que se tratarmos dentro da própria classe ela ignora se não for chamado o evento na classe principal, fazendo assim nosso software não dar esse erro feio na tela.

Então não é uma boa prática quando trabalhamos com eventos chamar direto as propertys que estão tratando os eventos, cria-se um método definindo sua regra de negócio, criando um jeito de validar esses eventos, não deixe essas responsabilidades para objetos de fora, a classe tem que se resolver, tem que resolver os problemas dela sem causar problemas maiores para outras.

Clique aqui para baixar os fontes desse projeto que usamos neste post.

Esse post é mais um que faz parte da Certificação especialista em programação orientada a objetos.

A Certificação Especialista Orientada a Objetos dará a você a oportunidade de melhorar seu software, otimizar o seu tempo e te dar a possibilidade de atender melhor os seus clientes. Conhecer a fundo esse paradigma e utilizar todos os seus benefícios irá facilitar muito a sua vida quando houver necessidade por parte de um cliente de um update rápido ou resolver um problema.

CLIQUE AQUI PARA SABER MAIS SOBRE A CERTIFICAÇÃO ESPECIALISTA EM PROGRAMAÇÃO ORIENTADA A OBJETOS





Faça sua busca

CATEGORIAS

POSTS RECENTES

E caso você tem interesse de conhecer mais sobre Eventos e Delegações, acesse o nosso portal do CLUBE DE PROGRAMADORES EM DELPHI
Você não terá só conteúdos relacionados ao Eventos e Delegações, mas uma quantidade enorme de conteúdos que poderá lhe ajudar muito no seu dia a dia, é uma verdadeira NETFLIX para os programadores Delphi.
Gostou?
Compartilhe:

Embarque no foguete com milhares de devs para aprender desenvolvimento, evoluir de forma contínua e se manter relevante no mercado.

Sobre
Dúvidas
Cadastre-se em nossa lista

Para ter acesso em primeira mão, a tudo que acontece na Academia do Código, basta se cadastrar em nossa lista

Grupo Thulio Bittencourt | Academia do Código

#FaçaPartedaHistória

Copyright © 2022 – Todos os direitos reservados