Camada de persistência de dados: DAO e ActiveRecord

Finalmente a camada de dados…

A camada, ou layer, de persistência ou de acesso aos dados é a parte da aplicação responsável por se comunicar com o banco de dados, ou com o framework de persistência, sendo os dois padrões mais conhecidos o DAO e o Active Record.

 

Active Record Vs DAO: O Show!

 

 

Numa aplicação orientada a objetos, e bem modelada e modular, temos a boa separação entre as responsabilidades de cada parte da aplicação. A parte de acesso ao banco de dados é uma das mais interessantes (a minha camada favorita!), ela é responsável por se conectar ao banco de dados e extrair, inserir e atualizar as informações. É responsável também por transformar modelos de Objetos em modelos Relacionais, o tal do ORM(Mapeamento Objeto Relacional), já que em muitos casos lidamos com banco de dados relacionais.

Podemos acessar de duas formas o banco de dados, usando um framework ou escrevendo SQL próprio. Hoje em dia existe uma variedade de frameworks, que programam os vários recursos necessários, de modo que costuma ser perda de tempo fazer o acesso direto ao Banco de Dados. Geralmente o ORM é feito através desses frameworks.

Temos dois padrões comuns para a comunicação com o BD/Framework: o Data Access Objet(DAO) e o Active Record (AR). Poderíamos acrescentar também o padrão Repositório, mas este terá um artigo próprio, na evolução deste tema. Os dois, DAO e AR, são padrões bem distintos e refletem abordagens extremamente diferentes na modelagem da aplicação.

 O Active Record se tornou extremamente popular com o framework Rails, para a linguagem Ruby, como a produtividade e simplicidade do framework revoluciona o desenvolvimento muitos abraçaram o padrão também em outros frameworks. O padrão é muito comum em frameworks para linguagens dinâmica, sendo até difícil achar um que não o use(nem tanto…).

 

Active Record Design Pattern

 

A modelagem em Active Record "invade" a camada do Modelo/Domínio da aplicação, definindo que um Objeto do modelo é o reflexo de uma "linha" do banco de dados. Assim sendo, os objetos que são persistentes devem estender/especializar uma classe ou interface que seja equivalente a uma linha do banco de dados. O Modelo é uma Extensão do Banco de Dados.

Essa interface, que o modelo ou classe genérica programa, define os métodos de interação com o banco de dados que um modelo possui. Então o próprio modelo é responsável pela sua persistência. O próprio objeto implementa métodos como Salvar, Restaura, Filtrar e etc. Além das funções de "Join". Desta forma o Active Record tem uma abordagem simples, visto de outras camadas é uma forma lógica e fácil de se trabalhar..

Nos frameworks, temos uma classe abstrata que é capaz de decidir como montar as queries SQL de acordo com as propriedades do objeto que a estender. Desse modo costuma bastar estender e não há necessidade de alterar o modelo, no máximo acrescentando informações ou meta-dados sobre a tabela equivalente, de acordo com a abordagem do framework.

O problema com o Active Record é que seu modelo fica com muita responsabilidade, Activer Redord não Escala!, e cria "BFC"s (Big Fucking Classes), já que o modelo além de conter as regras de negócio também cuida do banco de dados. Essa abordagem do Active Record é muitas vezes considerada uma falha no design da aplicação, pelo fato de que o Domínio passa a ser subordinado do Banco de dados. Este argumento pode ser rebatido já que na maioria dos sistemas, as classes do Modelo são apenas representações do Domínio, e não programam regras em si, e que essas regras passam estar representadas na persistência, não afetando o design de muitas aplicações.

Na prática, se temos uma classe Usuário esta deve estender uma outra classe, digamos Record. Record é uma classe provida pelo framework de persistência, ela implementa os métodos Select, Save e Delete. Ela também exige que seja implementado um método Configure pela classe filha, para definir os parâmetros do banco de dados. Assim sempre que precisamos buscar um usuário do banco de dados, usamos o método Select da própria classe Usuário, e por ai vai.

Se por um lado o Active Record atua de forma simples e explorando a flexibilidade dos frameworks de persistência de hoje e dinamismo das linguagens, o DAO por sua vez surge num ambiente de framework mais rígidos e que demandavam maior numero de chamadas e configurações. O DAO é praticamente o oposto do Active Record, em design. 

As classes DAO representam uma camada própria, e formam um pacote de acesso de dados, algumas vezes sob o pacote do modelo, algumas vezes um pacote independente e outras vezes parte do pacote de controladores. O mais comum é mesmo que o pacote de DAO fique subordinado ao Modelo, mas sem estendê-lo. Assim temos uma separação e relativa independência da camada de acesso dados e do Domínio.

 

DAO: Data Access Layer

 

 

O principio é que para cada Modelo, temos um DAO correspondente. Toda interação e configuração com o Banco de dados, ou com o framework de persistência, ficam na camada dos DAO. Então o DAO passa a programar métodos como Select, Delete, Insert, Update e outros que venham a ser necessário. Podem programar métodos mais específicos, como selecionarOndeNomeComecaComLetra ou cadastrarLista.

O DAO pode ser usado também como camada entre a aplicação e o modelo, ou entre diferentes aplicações. Passa-se a não acessar o modelo diretamente (com new) e usar os métodos do DAO para tal, mas essa abordagem nem sempre é usada. Assim, sempre que quiser uma instância de um Modelo, usa-se o DAO.

O uso de DAOs é(ou era ao menos) bem mais comum nos projetos Java. Como muitos frameworks ainda eram muito rígidos, e precisavam de mais código para fazer o ORM, ou para escrever queries mais personalizadas, esse código passou a residir na camada do DAO, algumas vezes tanto a descrição da transformação ORM quanto a montagem das queries através dos métodos do framework. Ou então, em casos onde as queries deviam ser muito precisas, a interação direta com o Banco de dados.

A abordagem de DAO costuma(va) ser associada a um design mais elegante, devido à separação das camadas. Assim tínhamos mais flexibilidade ao manipular o framework. Porém com a evolução dos frameworks, estes passam a perder um pouco a utilidade, já que são necessárias poucas chamadas aos framework e estes conseguem criar queries cada vez mais complexas automaticamente.

O DAO entra em "crise" com a evolução dos Framework, e sua utilidade passou a ser questionada, pois muitas vezes passaram simplesmente a programar os mesmos métodos que o framework provia, apenas repassando os chamados. Ficando entre um caso de programá-los por puro design e passando a ser overengineering. Com o conhecimento do padrão de Repositórios esses caso passou a ser entendido de outra forma..

Na prática, se temos um modelo Usuário, teremos um DAO UsuárioDAO. A classe Usuário não se altera, mas implementamos na UsuárioDAO os métodos necessários, como select, save e delete. Os métodos de UsuárioDAO fazem as validações necessárias e montam as chamadas para o framework de acordo com as especificações do Usuário, repassando então o objeto ao framework. Pode ainda implementar métodos especificos como validaLogin. Então ao precisar criar, recuperar ou salvar um objeto usa-se o DAO deste.

Apesar de ter escrito bastante, esta abordagem ainda é superficial. Apresentei os principais conceitos destes padrões, para exemplos práticos basta procurar frameworks para sua linguagem. Para o Active Record existem várias opções, mas na verdade não existem framework para DAO, já que DAO pode ser usado em conjunto com outras abordagem de persistência.

Um outro importante ponto na camada de persistência e acesso aos dados, é o padrão Repositório (repository), que solucionou alguns problemas dos DAO e se adapta melhor a estes frameworks mais flexíveis e menos complexos, mas este fica para um próximo texto.

10 ideias sobre “Camada de persistência de dados: DAO e ActiveRecord

  1. hehehe pois é Chris, já eu, como deve imaginar não tenho muita paciência para “escrever telas” :)

  2. Excelente explanação sobre os temas! Estou fazendo um trabalho sobre persitência de dados e o seu post ajudou muito! Valeu!

  3. Já utilizo há alguns meses Zend Framework e Doctrine e vejo que o Active Record é um grande facilitador do trabalho de persistência e também simples de compreenção e manipulação. Quanto ao DAO não tenho referências suficiêntes, mas acredito que AR seja de fato a e melhor opção para linguagens como o PHP.

    Parabéns pelo post.

  4. Também acho o AR mais prático e simples em aplicações dinâmicas, mas em modelos mais complexos prefiro trabalhar com repositórios para ter maior separação de responsabilidades no modelo.

Comentários encerrados.