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