MEME
Share on facebook
Share on twitter
Share on linkedin

Code Smell: Utilização errada de ferramentas para abstração de acesso a banco

 

Já dizia o Tio Ben para o Peter Parker em Homem Aranha: “grandes poderes trazem grandes responsabilidades.”

A utilização de frameworks de persistência e queries compiladas geralmente traz diversos benefícios ao desenvolvimento, tais como a compilação em si das queries, como o próprio nome diz, e a abstração do modelo físico, por exemplo. Por outro lado, se estas ferramentas forem utilizadas sem a devida atenção, várias dores de cabeça.

Obviamente, o problema não se restringe à utilização destes frameworks, mas ela pode potencializar a desatenção sobre estas situações, por muitas vezes serem encarados como “balas de prata” que resolvem todos os problemas de comunicação com os bancos de dados.

Quando esta situação pode ocorrer?

Utilização de operações de alto “custo” que levam tempo considerável de processamento dentro de alguma estrutura de repetição, conforme exemplo abaixo:

public void LogicaDeNegocioXYZ()

{

 foreach (Entidade entidade in listaEntidades)

 {

   //Faz alguma coisa

   PopularFilho(entidade);

   //Faz mais alguma coisa

 }

}

 

public void PopularFilho(Entidade entidade)

{

 //Faz alguma operação que vai ao banco ou qualquer operação pesada

}

Essa situação deve ser sempre evitada. Este equívoco citado no exemplo é facilmente cometido por programadores mais inexperientes, principalmente quando são utilizadas estruturas orientadas a objetos, como o framework Agilis ou Entity FW na Microsoft, por exemplo, conforme citado na introdução deste artigo.

Um caso típico são telas de consulta / filtro, onde é necessário retornar para um grid uma lista de colunas, sendo elas distribuídas em mais de uma entidade / tabela.

Exemplo:

Imaginem um exemplo hipotético das entidades NotaFiscal, ItemNotaFiscal e Produto.

Uma NotaFiscal tem uma lista de ItemNotaFiscal. Cada ItemNotaFiscal tem um membro Produto.

Imaginem uma “nota fiscal” ou cupom fiscal de uma padaria, onde você pede uma coxinha e um refrigerante. Neste caso, há uma nota fiscal, dois itens, sendo que cada item aponta para um produto (coxinha ou refrigerante).

Se é construído um grid para exibição dos itens da nota fiscal, e no caso de uso é necessário exibir o nome do produto, a situação citada acima pode ocorrer.

Se a tela exibe apenas os itens de UMA nota fiscal, este problema nunca será percebido, visto que a quantidade de itens é finita e pequena.

No entanto, se estivéssemos lidando com uma empresa maior que uma padaria e tivesse milhares ou milhões de produtos (uma montadora ou oficina industrial, por exemplo) e a tela tivesse um filtro por período e itens cujo valor é maior que X, esta situação poderia ocorrer e a tela ficaria lenta.

O que deve ser feito para resolver o problema?

Nestas situações é muito importante utilizar recursos de “eager loading” ou algum tipo de estrutura de cache para a entidade filha (desde que isto seja viável e a estrutura filha tenha um número grande de repetições e o cache faça sentido).

Estejam atentos a este tipo de situação!

Como mencionado na introdução, a utilização de ferramentas e frameworks de desenvolvimento geralmente traz muitos benefícios mas sua utilização deve ser acompanhada por desenvolvedores experientes!

Referências:

http://www.entityframeworktutorial.net/eager-loading-in-entity-framework.aspx

https://github.com/ccapndave/flextrine/wiki/Eager-and-lazy-loading

 

Por: Vinicius Paiva e Jéssica Saliba