Post: Reduzindo acoplamento utilizando Abstract Factory

Alessandro Medeiros

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

A cada novo chamado de seus clientes é uma dor de cabeça na hora da manutenção, acerta uma coisa e acaba tendo problema em outro lugar.

Seu projeto está totalmente acoplado que não consegue resolver esses problemas.

Saiba que usando a arquitetura MVC em seus projetos irá lhe proporcionar maior flexibilidade nas manutenções dos seus projetos, e melhorias.

E quando nós usamos o MVC em nossos projetos acabamos utilizando os padrões de projetos, e neste nosso post estarei lhe mostrando como reduzir o acoplamento utilizando o Abstract Factory.

Então vamos lá.

Quando criamos nossos projetos, acabamos colocando tudo na tela, como por exemplo um FDConnection+FDQuery+DataSource+DBGrid+DBNavigate.

O Delphi é muito bom por ser RAD, esse nosso exemplo é muito facil e pequeno, mas quando nossos projetos acabam crescendo, acabamos tendo problemas de acoplamento, tudo dentro do formulário, coisas que não é de sua responsabilidade.

Mas você deve estar dizendo, mas qual o problema disso?

O problema é que hoje você possui seu sistema com a conexão usando o FireDac, mas depois é desenvolvido uma nova conexão e você não pode migrar por estar totalmente acoplado com um driver de conexão, impedindo que seu projeto venha crescer.

Para isso vamos desacoplar todo esse projeto.

Trabalhando as boas práticas em projetos legados.

Primeiro devemos criar nossas interfaces de conexão.


type
iConexao = interface
    ['{2C36D4C2-243D-4B78-A74E-A0FD7F7499B3}']
    function Connection : TCustomConnection;
end;

iQuery = interface
    ['{F2C1F70F-7831-46B8-8590-DF5F9925353D}']
    function SQL(aValue : String) : iQuery;
    function DataSet : TDataSet;
end;

iEntidade = interface
    ['{CFB4689A-EB5D-4E6E-87CD-A8DD997C01D9}']
    function Listar(aValue : TDataSource) : iEntidade;
end;

Agora iremos precisar das classes que as implementam.

Vamos criar primeiro nossa classe de conexão FireDac, que implementa a interface iConexao.


Type
TModelConexaoFiredac = class(TInterfacedObject, iConexao)
private
    FConexao : TFDConnection;
public
    constructor Create;
    destructor Destroy; override;
    class function New : iConexao;
    function Connection : TCustomConnection;
end;

implementation

{ TModelConexaoFiredac }

function TModelConexaoFiredac.Connection: TCustomConnection;
begin
    Result := FConexao;
end;

constructor TModelConexaoFiredac.Create;
begin
    FConexao := TFDConnection.Create(Nil);

    FConexao.DriverName := 'FB';
    FConexao.Params.Values['Server'] := 'localhost';
    FConexao.Params.Values['Port'] := '3050';
    FConexao.Params.Values['Database'] := 'D:\BD\PDVUPDATES.FDB';
    FConexao.Params.Values['User_Name'] := 'SYSDBA';
    FConexao.Params.Values['Password'] := 'masterkey';
    FConexao.Connected := True;
end;

destructor TModelConexaoFiredac.Destroy;
begin
    FreeAndNil(FConexao);
    inherited;
end;

class function TModelConexaoFiredac.New: iConexao;
begin
    Result := Self.Create;
end;

Vamos também criar nossa classe de Query, que implementa a interface iQuery.


Type
TModelQueryFiredac = class(TInterfacedObject, iQuery)
private
    FParent : iConexao;
    FQuery : TFDQuery;
public
    constructor Create(Parent : iConexao);
    destructor Destroy; override;
    class function New(Parent : iConexao) : iQuery;
    function SQL(aValue : String) : iQuery;
    function DataSet : TDataSet;
end;

implementation

uses
    System.SysUtils;

{ TModelQueryFiredac }

constructor TModelQueryFiredac.Create(Parent : iConexao);
begin
    FParent := Parent;
    FQuery := TFDQuery.Create(Nil);

    if not Assigned(FParent) then
        FParent := TModelConexaoFiredac.New;
    FQuery.Connection := TFDConnection(FParent.Connection);
end;

function TModelQueryFiredac.DataSet: TDataSet;
begin
    Result := FQuery;
end;

destructor TModelQueryFiredac.Destroy;
begin
    FreeAndNil(FQuery);
    inherited;
end;

class function TModelQueryFiredac.New(Parent : iConexao) : iQuery;
begin
    Result := Self.Create(Parent);
end;

function TModelQueryFiredac.SQL(aValue: String): iQuery;
begin
    Result := Self;
    FQuery.SQL.Clear;
    FQuery.SQL.Add(aValue);
    FQuery.Active := True;
end;

E claro que iremos precisar de nossa classe de entidade Usuario que implementa iEntidade.


Type
TModelEntidadeUsuario = class(TInterfacedObject, iEntidade)
private
    FQuery : iQuery;
public
    constructor Create;
    destructor Destroy; override;
    class function New : iEntidade;
    function Listar(aValue : TDataSource) : iEntidade;
end;

implementation

{ TModelEntidadeUsuario }

constructor TModelEntidadeUsuario.Create;
begin
    FQuery := TCotrollerFactoryQuery.New.Query(nil);
end;

destructor TModelEntidadeUsuario.Destroy;
begin
    inherited;
end;

function TModelEntidadeUsuario.Listar(aValue: TDataSource): iEntidade;
begin
    Result := Self;
    FQuery.SQL('select * from usuario');
    aValue.DataSet := FQuery.DataSet;
end;

class function TModelEntidadeUsuario.New: iEntidade;
begin
    Result := Self.Create;
end;

Lembrando que estamos programando a interface, fazemos isso para que possamos reduzir o acoplamento, mas para que não tenhamos nenhuma dependência e o acoplamento seja totalmente zero, iremos precisar de um Abstract Factory.

Desta forma precisamos criar uma interface iFactoryQuery.


...

iFactoryQuery = interface
    ['{0C73F577-03B1-4A16-ACFF-0F8072D78D3B}']
    function Query(Connection : iConexao) : iQuery;
end;

...

Na sua classe que a implementa nós reduzimos o acoplamento, ao criarmos a fabrica de query, fazendo desta forma não ficamos refem de nenhum componente de conexão e manipulação de dados, sendo assim podemos trocar nossa conexão para DBX, Unidac, Zeos, sem nenhum problema.

Não importa o que iremos utilizar, pois a fabrica de query reduz esse acoplamento, fazendo com que a camada de visão não precise saber qual componente estamos usando, veja só o código a baixo.


Type
TCotrollerFactoryQuery = class(TInterfacedObject, iFactoryQuery)
private
public
    constructor Create;
    destructor Destroy; override;
    class function New : iFactoryQuery;
    function Query(Connection : iConexao) : iQuery;
end;

implementation

{ TCotrollerFactoryQuery }

constructor TCotrollerFactoryQuery.Create;
begin

end;

destructor TCotrollerFactoryQuery.Destroy;
begin
    inherited;
end;

class function TCotrollerFactoryQuery.New: iFactoryQuery;
begin
    Result := Self.Create;
end;

function TCotrollerFactoryQuery.Query(Connection : iConexao) : iQuery;
begin
    Result := TModelQueryFiredac.New(Connection);
end;

Desta forma o nosso projeto pode ser mudado suas engine de conexão sem nenhum problema, pois a fabrica de query abstrai tudo isso evitando o acoplamento.

Viu como ficou muito simples e não ficamos refém de nenhum componente.

 

 

Você ainda encontra-se refém de componentes?

Seu projeto não consegue acompanhar as novidades do mercado da tecnologia?

As melhorias e manutenções do seu software tem sido uma dor de cabeça constante?

Saiba que ao aplicar a metodologia MVC em seu projeto, usando as boas práticas, verá uma enorme mudança na sua vida e nos seus projetos.

Esse post foi retirado do Treinamento CERTIFICAÇÃO ESPECIALISTA EM ARQUITETURA MVC.

O QUE VOCÊ IRÁ APRENDER?

A Certificação Especialista Arquitetura MVC 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 ARQUITETURA MVC






Faça sua busca

CATEGORIAS

POSTS RECENTES

E caso você tem interesse de conhecer mais sobre Reduzindo acoplamento utilizando Abstract Factory, acesse o nosso portal do CLUBE DE PROGRAMADORES EM DELPHI
Você não terá só conteúdos relacionados ao Reduzindo acoplamento utilizando Abstract Factory, 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