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
