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

Trabalhar orientado a objeto da 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.

Neste post irei falar sobre a orientação a eventos, não estou fugindo da orientação a objetos, mas vamos atribuir ao POO.

Dentro do Delphi nós conseguimos mesclar tanto orientação a eventos quanto a orientação a objetos de forma prática e muito fácil.

A orientação a eventos veio para resolver uma questão que no POO daria um pouco de trabalho para resolvermos, pensa comigo por exemplo que eu tenho uma classe que é um botão e eu coloque dois, três, quatro, cinco botões na tela e digamos que para cada clique desses botões eu tenha que atribuir uma função diferente, se trabalharmos puramente com POO, o que irá acontecer é que teremos que ter especializações da minha classe botão, uma para cada ação, isso seria o correto do POO.

Na orientação a evento permite que agente delegue funcionalidade  de outras classes para uma classe especifica, então eu posso ter uma classe fora desse conceito, posso ter simplesmente uma classe botão e as outras classes delegarem funções da minha classe botão, este é o conceito mais simples de entender, é uma forma de tentar representar isso de um jeito mais simples.

Todas as vezes que você trabalha com orientação vai existir momentos em que a cada alteração do estado de uma propriedade, de um método ou algo do tipo, você avise isso a outras classes, outros objetos que estão trabalhando com aquele objeto em si, é esse ponto que a orientação a objeto resolve.

Vamos na prática

Em meu formulário irei por um memo na tela e iremos usar nossos eventos para trabalhar com esse memo.


Então como eu declaro um evento?

Vamos criar dentro de nossa classe pessoa eventos para que possamos trabalhar.

Antes de nossa classe pessoa iremos criar um evento que será responsável por exibir no memo qual foi o usuário que foi cadastrado.


type
    TEventMemo = procedure(Value : String) of object;

...

Quando declaramos um evento podemos nomear da forma que quisermos.

Se observarmos é muito semelhante você declarar um método dentro da classe, nós passamos uma procedure, vamos passar um valor string, e pode ver o que mudou é somente o final da declaração que é o of object.

Eu tenho uma procedure que está tipificando um evento, e agora nós iremos utilizar esse evento dentro de nossa classe Pessoa.


TPessoa = class
    private
       Conexao : IConexao;
       FUF: String;
       FNome: String;
       FCidade: String;
       FEndereco: String;
       FTelefone: String;
       FEventMemo: TEventMemo;
       procedure SetCidade(const Value: String);
       procedure SetEndereco(const Value: String);
       procedure SetNome(const Value: String);
       procedure SetTelefone(const Value: String);
       procedure SetUF(const Value: String);
       procedure SetEventMemo(const Value: TEventMemo);
    public
       constructor Create(aConexao : IConexao); virtual;
       procedure Cadastrar;
       procedure CriarFinanceiro;
       function Tipo : String; virtual; abstract;
       property Nome : String read FNome write SetNome;
       property Telefone : String read FTelefone write SetTelefone;
       property Endereco : String read FEndereco write SetEndereco;
       property Cidade : String read FCidade write SetCidade;
       property UF : String read FUF write SetUF;
       property EventMemo : TEventMemo read FEventMemo write SetEventMemo;
end;

Você pode ver que criamos uma property que nada mais e nada menos que é uma variável do tipo TEventMemo.

E agora toda vez que quisermos exibir uma informação no memo  iremos usar o TEventMemo.

Quando eu for cadastrar, logo após o método gravar eu irei passar o meu evento onde iremos passar o parâmetro string que definimos na sua criação.


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;
        EventMemo(Nome + ' Cadastrado com Sucesso');
    finally
        Lista.Free;
    end;
end;

Toda vez que executarmos o método Cadastrar da classe Pessoa ele irá por a mensagem e o evento que irá trata-la.

Você pode observar que de maneira nenhuma nós colocamos algum valor dentro do memo, colocamos ele no formulário e não fizemos nada com esse memo.

Agora que a implementação ta ficando legal, por que?

Se pegarmos o mesmo código do evento e colocarmos agora no método CriarFinanceiro da nossa classe Pessoa iremos ter a mensagem de cadastro para o método CriarFinanceiro.


procedure TPessoa.CriarFinanceiro;
var
    Lista : TStringList;
begin
    Lista := TStringList.Create;
    try
        Lista.Add('Nome:' + Nome);
        Lista.SaveToFile(Nome + '_Financeiro.txt');
        EventMemo(Nome + ' Cadastrado o Financeiro com Sucesso');
    finally
        Lista.Free;
    end;
end;

Você repere numa coisa, minha classe Pessoa não sabe o que irá acontecer com esse TEventMemo ela simplesmente sabe que devemos passar um tipo string para ela e mais nada, quem irá tratar o que irá acontecer com esse TEventMemo é quem está chamando a classe, no caso é o nosso form principal, ao cadastrarmos um cliente por exemplo, ao tentarmos chamar o nosso EventMemo ele espera uma procedure que tem um parâmetro string.

Vamos criar uma procedure no form principal que deva seguir os padrões definidos pelo nosso evento.


...

private
    { Private declarations }
    procedure ExibeMensagemMemo(Value : String);

...

procedure TForm1.ExibeMensagemMemo(Value: String);
begin
    Memo1.Lines.Add(Value);
end;

Qualquer procedure que tivermos dentro de nossa classe que tenha um parâmetro string ela pode ser atribuída ao nosso EventMemo  da classe pessoa.


procedure TForm1.Button1Click(Sender: TObject);
var
    Cliente : TPessoa;
begin
    Cliente := TPessoa.Create(TConexaoMySQL.Create);
    try
        Cliente.EventMemo := ExibeMensagemMemo;
        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;

Você pode observar que no código acima estamos atribuindo para o EventMemo a nossa procedure ExibeMensagemMemo, neste ponto estou só apontando, criando um ponteiro para o meu evento.

Irei cadastrar agora meu cliente e veja o nosso resultado.

Viu a mensagem no nosso memo?

Essa mensagem foi para o memo sem que nossa classe Pessoa soubesse o que foi feito.

Nossa classe pessoa não tem conhecimento nenhum do memo.

Viu como é simples e muito legal a utilização de eventos no Delphi, você ganha uma performance muito grande na hora de modelar o comportamento das suas classes utilizando eventos, você consegue delegar essas atribuições dos estados sem precisar mexer dentro de sua classe sem precisar que sua classe venha saber o que está acontecendo.

Esse post foi retirado do treinamento Certificação Especialista em programação Orientada a objetos.

O QUE VOCÊ IRÁ APRENDER?

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 E SAIBA MAIS SOBRE O TREINAMENTO CERTIFICAÇÃO ESPECIALISTA EM PROGRAMAÇÃO ORIENTADA A OBJETOS.