Independência de Banco de Dados

Um requisito não-funcional importante na engenharia de software é a escolha do repositório de dados da aplicação. A princípio, isso não constitui um grande problema. Afinal, durante a construção do sistema, é sulficiente se adaptar a infra-extrutura já existente no estabelecimento que irá usar o sistema. Se não houver um parque de informática definido, é comum escolher um banco de dados gratuito que normalmente atende a maioria das situações ou, mesmo, comprar licenças de uso de algum banco de dados comercial.

O problema começa na manutenção do sistema. A empresa decide, por exemplo, mudar o banco de dados padrão. Isso pode acontecer por vários motivos: contenção de custos, limitações do banco de dados atual, mudança da plataforma, etc. Aí pode ser um transtorno para os desenvolvedores: migrar os dados e modificar o sistema para se adaptar à nova situação. Sem falar nas mudanças e reinstalações que poderão ocorrer nas máquinas dos usuários. E se forem muitos usuários?! E se for pra ontem?! E se o pessoal pra fazer essas mudanças for limitado?! Veja que o desgaste gerado por esta “mudança” pode crescer de maneira exponencial. Eu já passei por isso. Posso garantir que os problemas envolvidos podem exigir várias noites de pesquisas e aprendizado instantâneo para poder continuar merecendo a confiança dos seus superiores. Fui obrigado a mudar duas vezes de plataforma de desenvolvimento em menos de dois anos. Hoje cheguei a conclusão que só existem duas plataformas que se adaptam bem a quase todos os cenários no mundo da micro-informática: .NET ou Java.

Pensando nisso decidi postar algumas considerações visando atingir o tão sonhado grau de indepêndencia de banco de dados.

Vamos analisar a seguinte situação:

Acesso direto a base

Note o seguite:

  1. A aplicação desktop faz acesso direto a base de dados. Todas a regras de negócio e persistência de dados são feitas diretamente pela aplicação. Essa arquitetura é muito utilizada pelos programadores Delphi, VB e similares.
  2. Numa aplicação que utiliza servidor WWW, o browser faz requisições ao servidor que por sua vez acessa a base diretamente, da mesma forma que uma aplicação desktop. Os sites no servidor web contém regras de negócio e são responsáveis pelo acesso aos dados. Isso é comum para programadores ASP, JSP, PHP, ColdFusion e similares.

Uma maneira de atingir a indepêndencia de banco neste contexto é utilizar somente instruções SQL ANSI para persistir dados. Mesmo assim isso possui alguns incovenientes. Numa aplicação desktop que está instalada em várias máquinas, qualquer mudança na regra de negócio implicará em reinstalação em todas as máquinas que fazem uso dessa aplicação. Se forem muitos usuários? Se os usuários não sabem instalar sistema? Certamente o help desk vai ter trabalho dobrado pra implantar a nova versão. Utilizando servidor WWW isso ameniza e muito o problema. Basta atualizar o servidor e tudo bem. Todos os usuários terão a nova versão no seu browser. Mas a depender de como essas páginas foram criadas os programadores terão que atualizar a regra ou as configurações de banco em cada página do site. Sem falar que nem sempre é possível desenvolver com instruções SQL ANSI apenas. Uma função de banco, uma VIEW, procedure ou trigger precisa ser reescrita no momento que o banco for trocado.

Quando eu utilizava o Delphi ou o PHP optei pela seguinte solução: Minhas aplicações serviam apenas como GUI. As regras de negócio e a persistência de dados era responsabilidade das procedures de banco. Usava também usuários de banco, functions, roles e views. Triggers não utilizava por serem um tipo de procedures.

Fig02 Acesso a base por procedure

Quando tinha que mudar alguma regra, apenas fazia nas procedures. Mudanças na GUI eram mínimas. Assim não precisava reinstalar as aplicações Delphi toda vez que mudasse alguma regra da aplicação. No PHP, da mesma forma. Só mudava a página se houvesse extrema necessidade. Era ótimo a princípio. Mas… E a independência de banco??? Assim a situação só piora o problema. Ganha de um jeito, na manutenção da regra e help desk, mas perde na independencia de banco, ou seja, teria que reescrever todas procedures caso mudasse o banco. Conclusão: abandonei completamente o uso das procedures, views, roles, functions, usuários de banco e tudo mais que dependa diretamente do banco de dados. Minhas aplicações tiveram que ser reescritas completamente em outra arquitetura.

Uma solução padrão para o problema da independência de banco é utilizar um padrão de projeto chamado DAO. Isso mesmo, PADRÃO DE PROJETO. Padrão DAO faz parte de um conjunto de padrões que resolvem problemas recorrentes. Mas isso é outra história…

Acesso a base por um DAO

Cria-se um meio, que normalmente é uma classe da orientação a objetos, por onde a aplicação fará todas as chamadas ao banco, de forma que mudar o banco significaria apenas mudar alguns atributos dessa classe. Ou seja, a classe DAO iria se moldando de acordo com algumas informações passadas no seu construtor. É possivel que alguns métodos precisem ser adaptados por causa do SQL. Mas utilizar SQL ANSI diminue bastante esta necessidade. Eu comecei a fazer isso também. O problema maior é que construir uma classe dessas não pode ser um trabalho solitário. A programação da classe cresce muito. Afinal, para que fique boa, todas as possibilidades do SQL tem que estarem previstas: inserts, updates, deletes e selects e para todos os bancos de dados envolvidos. Se não, pode-se construir uma classe DAO com menos recursos e ir aprimorando a medida que necessidades surjam.

Uma solução que eu considero muito boa é construir uma classe DAO que faça uso de algum framework de persistência.

Fig04 Acesso a base por um DAO e persistência

A responsabilidade de persistir os dados fica para o framework que normalmente já vem preparado para utilizar vários bancos de dados, enquanto a classe DAO da aplicação apenas herda essas características. Eu aconselho a utilização de um framework muito bom, tanto para o Java quanto para .NET: o Hibernate.

O Hibernate consegue ser independente de banco de dados devido a algumas características principais:

  1. através de mapeamento de entidades do SGBD como classes da linguagem e via arquivos XML;
  2. ampliando a linguagem SQL para HQL (Hibernate Query Language). Esta linguagem manipula objetos e coleções que, depois, o próprio framework converte para SQL que o SGBD entende. Essa conversão é feita utilizando os arquivos XML de mapeamento, configurações de dialeto do banco e drivers de comunicação. Também pode-se utilizar outras formas de montagem do SQL, por exemplo, utilizando métodos de classes. Esses métodos recebem parâmetros que montam o SQL também utilizando os arquivos XML de mapeamento, configurações de dialeto do banco e drivers de comunicação;

Parece complicado mas não é. Inclusive tudo isso é muito produtivo. Desenvolver aplicações sobre essa ótica aumenta bastante a produtividade. Linhas de cada tabela do banco tornam-se objetos e as colunas, propriedades desses objetos. O resultado dos selects do SQL é visto como coleções de objetos e os DML’s são vistos como metódos das classes de regra de negócio. É responsabilidade do framework converter tudo isso para o SQL que o banco entenda, e essa conversão deve ser de acordo com o dialeto do banco escolhido e definido em algum arquivo de configuração.

Dessa forma mudar de SGBD significa migrar os dados de um banco pra outro, mudar a configuração de dialeto e alterar, se for o caso, os arquivos XML de mapeamento das entidades. Posso garantir que poucas modificações são necessárias para migrar um sistema do SQL Server para Oracle, se voce utilizar um framework de persistência como Hibernate durante o desenvolvimento. Se a migração for, por exemplo, do Firebird para Oracle ou vice-versa as modificações se resumem a uma ou duas linhas no arquivo de configuração, além, claro, da migração dos dados.

Bom, é isso. Espero que este pequeno artigo seja útil e sirva como roteiro pra quem deseja programar com independência de banco.

Sobre Reginaldo Jr.

Bel. em Ciência da Computação com mais de 20 anos de experiência em desenvolvimento de sistemas. Atualmente desenvolve aplicações para web. Interesse em dispositivos móveis, sistemas médico-hospitalares, SAP/ERP, computação ubíqua e novas tecnologias,
Esse post foi publicado em Todos e marcado , , , , , , , , , , , . Guardar link permanente.

11 respostas para Independência de Banco de Dados

  1. José Luis disse:

    Muito bom parabéns

    • reginaldojr disse:

      Olá. Que bom que gostou agradeço o elogio. Se tiver alguma coisa pra contriubir fique a vontade. Obrigado!

  2. José Luis disse:

    Gostaria de saber qual a diferença entre Independência de dados e Independência de banco de dados (banco de dados foi explicado nessa sessão)

    • reginaldojr disse:

      Olá. Qualquer mudança física ou lógica no banco de dados não afeta os aplicativos. É como voce alterar o tamanho ou tipo de campos de uma tabela e o programa se adequa sem maiores problemas. Mais ou menos isso.

  3. Renato Nunes disse:

    Agradeço o artigo….muito instrutivo. Valeu!!!

  4. Luiz Antonio disse:

    Muito bom parabéns

  5. diegorafaelss disse:

    Comecei a desenvolver partes de um pequeno sistema que já estava em desenvolvimento, e estou tendo dificuldades no desenvolvimento das classes em PHP, porque a maioria das regras de negócio está definida em triggers do BD porque o desenvolvedor antigo era iniciante em PHP. Não tenho acesso para gerenciar livremente a base de dados de teste do sistema e minha forma de pensar e resolver os problemas nem sempre são coincide com a da pessoa que gerencia a o BD.
    A base já tem diversas inconsistências em suas informações e a cada dia surgem mais. Gostaria de manipular as todas as regras de negócio diretamente na aplicação.

    Que dica você poderia para solucionar estes problemas, e dar um seguimento mais rápido e seguro ao projeto?

    • reginaldojr disse:

      Primeiramente obrigado pela visita e interesse em nosso trabalho.

      Respondendo a sua questão…. Na minha opinião o ideal seria reescrita do sistema utilizando algum padrão e arquitetura previamente planejada e em uma outra plataforma como Java ou .NET. Do Jeito que está, mexer nisso pode ser muito trabalhoso e certamente poderá provocar vááááários outro bugs.

      Uma segunda opção seria remover essas triggers e trabalhar com stored procedure (o papel das triggers seria realizado pelas procedures). Assim voce já teria todo controle de regras em um único local, sem falar que stored procedure é garantia de processamento rápido. Claro que essa opção não dá independẽncia do banco de dados.

      Tem uma terceira opção: aprender a mexer com classes no PHP para poder negociar com o DBA a remoção das triggers, transformando o banco de dados em repositório de dados. Nenhuma regra estaria nele, a não ser aquelas básicas (relacionamentos, constraints, etc.)

      Voce teria que simular um ambiente de testes em outro computador, construir as classes em PHP que pudessem fazer o papel das triggers para posteriormente remove-las; realizar testes e apresentar ao DBA ou superiores as suas modificações, mostrando por que seria vantajoso essa nova forma de trabalhar. Mas pra isso voce terá que aprender a mexer com classes no PHP.

      Seja qual for a escolha novos problemas vão surgir. A equipe toda deve estar ciente disso. A questão principal é qual arquitetura haverá maior facilidade de solucionar os problemas (manutenibilidade).

      É isso. Espero ter ajudado.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alteração )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alteração )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alteração )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alteração )

Conectando a %s