Post: Injeção de Dependência

Alessandro Medeiros

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

Neste post nós vamos ver um pouco sobre injeção de dependência.

O que é isso que as pessoas falam? parece algo tão distante, parece complicado, algo que talvez você diga que nunca irá utilizar.

Injeção de dependência é algo muito simples, vamos imaginar comigo mais ou menos a seguinte situação.

Você acorda pela manhã e por exemplo você quer ler um jornal, o que você faz?

Você sai da sua casa, vai até o jornaleiro, compra o jornal e volta.

Você sozinho, como uma classe unitária, resolveu o problema, você foi até o jornaleiro e voltou, só que isso lhe deu um trabalho muito grande, sendo que você quer reduzir esse trabalho, ou seja, você não quer resolver tudo dentro da sua classe, você quer por exemplo acordar pela amanhã, abrir a porta da sua casa e o jornal esteja no chão, e você simplesmente pega o jornal e entre para ler.

Só que para o jornal chegar até você alguém tem que ter feito o trabalho de buscar o jornal na banco e levar até a sua casa, neste momento que você injeta a dependência de um entregador.

Então agora você como uma classe unitária, não precisa mais de ter o trabalho de ir lá no jornaleiro e buscar o seu jornal, alguém irá fazer isso e já vai lhe entregar o jornal, isso é resumindo a injeção de dependência.

Você irá fazer com que a sua classe unitária, receba uma outra classe nesse nosso exemplo, vamos botar ai algo como TPessoa e TJornaleiro, como por exemplo, você vai receber como TPessoa a injeção de dependência de TJornaleiro, que irá já vai lhe entregar o jornal pronto.

Vamos dentro do código ver como podemos fazer isso?

É bem simples e usamos muito essa questão, por exemplo, nota fiscal e nota itens, você tem a classe de nota, e na classe de itens por algum motivo você precisa de algumas informações da nota, geralmente o que agente faz é declarar uma variável global, e não é bem por ai.

Nós iremos trabalhar com conceitos de interfaces, onde iremos criar uma interface para nota, e nota itens.


type
    iNota = interface
    ['{E21F5F46-BB95-4CAE-BB84-00A2EE0D1F32}']
end;

iNotaItens = interface
    ['{B08255AE-847B-4AB8-BD0F-CCED838BA311}']
end;

Então nós temos essas duas interfaces, e temos que ter duas classes que as implementa.


TNota = class(TInterfacedObject, iNota)

end;

TNotaItens = class(TInterfacedObject, iNotaItens)

end;

Então você imagine nesse nosso cenário que a classe de TNotaItens precisa conhecer, por exemplo, o numero da nota, na hora que eu for salvar um item eu preciso do numero da nota.

Então na minha interface iNota um método


...

iNota = interface
    ['{E21F5F46-BB95-4CAE-BB84-00A2EE0D1F32}']
    function Numero : Integer;
end;

...

TNota = class(TInterfacedObject, iNota)
    function Numero : Integer;
end;

A nossa classe de nota itens precisa conhecer um numero da nota por algum motivo.

Eu tenho as minhas interfaces e as classes que as implementa, e agora como que eu faço uma injeção de dependência?

Se nós vamos acessar a nossa nota, primeira coisa que devemos ter é uma variável privada em nossa classe de nota itens do tipo iNota, pos as boas práticas nos orienta sempre a trabalhar orientado a interface e não a classe, por este motivo nós não declaramos nosso objeto do tipo da classe TNota, e sim do tipo da interface iNota.


TNotaItens = class(TInterfacedObject, iNotaItens)
private
    FNota : iNota;
end;

Eu já tenho um objeto da nota em nossa classe de nota itens, só que eu preciso instanciar ela, se eu instanciar dentro da nossa classe de nota itens, indo no Create, por exemplo, declarando FNota := FNota.Create, eu estarei criando uma nova nota, se eu criar uma variável global para cessa-la, não é uma boa prática, então o que agente deve fazer?

Agente irá receber esse objeto por injeção de dependência a nossa nota já com todos os elementos já preenchidos.

Então como seria isso?

Dentro do public, isso em nossa classe de nota itens, dentro do create dessa classe nós criamos uma dependência, onde a classe TNotaItens não poderá ser criada se não estiver recebendo um objeto de TNota.


TNotaItens = class(TInterfacedObject, iNotaItens)
private
    FNota : iNota;
public
    constructor Create(Nota : iNota);
end;

Desta forma eu injetei uma dependência, então a nossa classe TNotaItens tem a dependência de TNota para funcionar.

Essa é a forma mais simples de ilustrarmos as injeções de dependências.

Isso serve muito para substituirmos heranças, variáveis globais, eu não preciso que o meu objeto herde do outro, para implementar métodos abstratos e tudo mais, eu preciso da nota, então manda ela por injeção de dependência, ai eu passo a utilizar o objeto que está instanciado nessa injeção, eu passo a ter acesso a todos os métodos desse objeto desta forma.

Isso é muito simples e muito utilizado.

Vamos colocar um botão em nossa exemplo só para ver isso funcionando

Dentro desse botão iremos realizar alguns procedimentos para que possamos ver a nossa injeção de dependência funcionando.

Mas primeiro vamos criar um método em nossa interface iNotaItens que irá retornar numero.


iNotaItens = interface
    ['{B08255AE-847B-4AB8-BD0F-CCED838BA311}']
    function RetornaNumero : Integer;
end;

..

TNotaItens = class(TInterfacedObject, iNotaItens)
private
    FNota : iNota;
public
    constructor Create(Nota : iNota);
    function RetornaNumero : Integer;
end;

...

constructor TNotaItens.Create(Nota: iNota);
begin
    Fnota := Nota;
end;

function TNotaItens.RetornaNumero: Integer;
begin
    Result := FNota.Numero;
end;

Observe que criamos o método em nossa interface iNotaItens, passamos para a classe que à implementa, e passamos no create a injeção de dependência para o objeto FNota, desta forma no método RetornaNumero já temos em seu retorno o método Numero da classe TNota, sendo assim todas as vezes que chamarmos o método RetornaNumero, ele irá chamar o numero da nota.

Desta forma no botão do nosso formulário iremos instanciar a nota, e passar essa instancia para o create da classe TNotaItens, iremos dar um ShowMessage no método RetornaNumero.


procedure TForm2.Button1Click(Sender: TObject);
var
    Nota : iNota;
    NotaItens : iNotaItens;
begin
    Nota := TNota.Create as iNota;
    NotaItens := TNotaItens.Create(Nota) as iNotaItens;

    ShowMessage(NotaItens.RetornaNumero.ToString);
end;

Se tudo correr bem na nossa injeção de dependência, ele deverá retornar o numero que deixamos default no método Numero da classe TNota.


function TNota.Numero: Integer;
begin
    Result := 10;
end;

Por que tem que retornar esse numero?

Porque nós a injetamos por dependência.


...

NotaItens := TNotaItens.Create(Nota) as iNotaItens;

...

Vamos ver agora como ficou nosso projeto usando injeção de dependência?

Nós utilizamos isso muito dentro de nosso projetos, muito melhor que usar herança, variável global e outras coisas, e outra coisa, deixamos o código muito mais organizado.

Tudo que a nota itens precisa para funcionar tem dentro do objeto nota.

Viu como é muito simples trabalhar usando injeção de dependência?

Deixamos de espalhar variáveis para tudo que é lugar no nosso código, e melhoramos muito a qualidade dele.

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 Injeção de Dependência, acesse o nosso portal do CLUBE DE PROGRAMADORES EM DELPHI
Você não terá só conteúdos relacionados ao Injeção de Dependência, 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.

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 © 2024 – Todos os direitos reservados