Você está na página 1de 10

Aplicao do Padro Data Access Object (DAO) em Projetos Desenvolvidos com Delphi

Marcelo Sardagna1, Adilson Vahldick1 Departamento de Sistemas e Computao Universidade Regional de Blumenau (FURB) Blumenau, SC Brasil
msardagna@gmail.com, adilsonv77@gmail.com
1

Resumo. Este artigo apresenta uma proposta para utilizao do padro Data Access Object em aplicaes desenvolvidas com Delphi utilizando os componentes DBExpress. Em seguida descreve uma ferramenta desenvolvida para alterar o cdigo fonte em arquivos PAS e DFM de aplicaes legadas em Delphi para empregar essa proposta de utilizao do padro. Abstract. This work presents a proposal for utilizing Data Access Object pattern at Delphi applications with DBExpress components. Next describes a tool developed to modify the source code in PAS and DFM files from legacy applications in Delphi for utilizing the pattern propose in this work.

1. Introduo
O ambiente de desenvolvimento Delphi um ferramental que permite o desenvolvimento rpido de aplicaes, pois ele se baseia em arrastar componentes para a janela, criar ligaes entre esses componentes e alterar suas propriedades. O sucesso do Delphi se deve pouca exigncia tcnica dos programadores para desenvolver uma aplicao, pois a maior parte do trabalho esse arrastar e conectar os componentes. A necessidade de programar linhas de cdigo minimizada com a possibilidade de codificar todas as regras de negcio na prpria janela onde os componentes foram arrastados. Por outro lado, a rapidez e a facilidade em desenvolver as aplicaes dessa maneira levam a srios problemas na manutenibilidade. A reusabilidade baixa, basicamente por dois motivos: (i) o cdigo programado na janela (descendentes da classe TForm), e (ii) os componentes so todos atrelados janela. No Delphi costuma-se programar nas prprias janelas, logo, a reusabilidade, quando acontece, de janelas e no de regras de negcio. Entretanto, o Delphi permite o desenvolvimento orientado a objetos, onde podem se programar as regras de negcios em classes, ou mesmo em componentes, e conectar esses objetos nas janelas aumentando o nvel de reusabilidade. Contudo, quem inicia com Delphi, se encanta com as facilidades proporcionadas pelo ambiente e somente se depara com os problemas de manuteno num segundo momento, quando o cliente solicita mudanas nos requisitos, ou se deseja aproveitar um projeto para outros clientes. Uma das situaes que pode se notar a baixa reusabilidade quanto conexo com banco de dados. As expresses SQL so informadas diretamente nos componentes,

seja nas janelas ou num Data Module. As mudanas no projeto do banco de dados exigem acessar componente a componente, havendo por vezes a necessidade de procurar nas janelas de todo o projeto, e modificar as expresses para atender essas alteraes. Na ltima dcada tem-se dedicado esforos no estudo e disseminao dos padres de projeto para aumentar a reusabilidade de software e por consequncia diminuir o custo de manuteno. Segundo Gamma et al (2000), Valente (2003), Shalloway e Trott (2004) e Fowler (2006), os padres de projeto permitem a reutilizao de arquiteturas e projetos bem sucedidos, reaproveitando solues e a experincia dos modeladores, assim como estabelecendo um vocabulrio comum para os envolvidos no desenvolvimento, fazendo com que melhore-se a comunicao entre eles. Alm disso, a adoo de padres requer adaptao dos projetos, e com isso naturalmente as aplicaes precisam ser bem arquitetadas para tal reaproveitamento, criando assim um ciclo virtuoso entre a nova aplicao e os padres j adotados por uma equipe. Na busca de uma soluo para melhorar a manutenibilidade das aplicaes em Delphi quanto conexo de banco de dados proposto neste trabalho uma estratgia de adoo do padro de projetos Data Access Object (DAO), que abstrai e encapsula os mecanismos de acesso a banco de dados (AECE, 2005), adaptado na utilizao de componentes DBExpress. Tambm demonstrada a ferramenta implementada para empregar essa estratgia em aplicaes Delphi legadas. Esse artigo estruturado da seguinte forma: primeiro apresentada uma breve fundamentao sobre o padro DAO, para em seguida apresentar os componentes Delphi considerados nesse trabalho; na seo seguinte apresentada a estratgia de utilizao do padro DAO em aplicaes Delphi; na seo subsequente demonstrada a ferramenta implementada para alterar projetos em Delphi para utilizar o padro; e por ltimo so apresentadas as concluses em relao ao estudo feito nesse trabalho.

2. Data Access Object (DAO)


O padro DAO consiste em abstrair o mecanismo de persistncia utilizado na aplicao. A camada de negcios acessa os dados persistidos sem ter conhecimento se os dados esto em um banco de dados relacional ou um arquivo XML. O padro DAO esconde os detalhes da execuo da origem dos dados (SUN, 2007). A figura 1 apresenta a estrutura do padro DAO. A classe DataAccessObject encapsula o acesso aos dados, que por sua vez mantido pela classe DataSource que pode ser um arquivo XML, uma base de dados ou algum servio remoto, ou seja, a origem dos dados. A classe BusinessObject representa a aplicao, ou tambm conhecida como cliente do padro, que usa um objeto DataAccessObject. Ao utilizar esse objeto DataAcessObject, o objeto cliente recebe ou envia um objeto TransferObject. Esse objeto contm os dados a serem enviados ou trazidos da origem dos dados, e normalmente referem-se aos campos de um registro.

Figura 1 Estrutura do padro DAO

Exemplificando com uma aplicao real, uma classe ProdutoDAO (que faz o papel de DataAccesObject) pode ser responsvel pelo acesso aos dados do cadastro de produtos. Um produto desse cadastro pode ser representado por uma classe Produto (que desempenha o papel de TransferObject). A classe ProdutoDAO pode ter um mtodo para leitura que recebe um chave, busca o produto na origem de dados (que pode ser um banco de dados), cria um objeto Produto com os dados do produto e devolve esse objeto aplicao. A classe ProdutoDAO pode ter um mtodo para salvar que recebe como parmetro um objeto Produto e com essas informaes inclui ou altera um produto na origem dos dados.

3. Componentes DBExpress
O pacote de componentes DBExpress est disponvel a partir da verso 7.0 do Borland Delphi e permite acesso aos banco de dados sem necessidade de configurao ou aplicaes adicionais no Windows, como acontecia nas verses anteriores (BORLAND, 2005). A conexo e o acesso com os bancos de dados feito com as prprias DLLs (Dynamic Link Library) fornecidas pelos fabricantes dos SGBDs (Sistema Gerenciador de Banco de Dados). Os componentes DBExpress abstraem e encapsulam o acesso ao banco de dados, mas no podem ser considerados como uma aplicao do padro DAO na sua forma mais pura, pois eles no utilizam objetos TransferObject. Os dois principais componentes so o TSQLConnection e TSQLQuery. No componente TSQLConnection se configura o banco de dados, ou seja, qual a DLL e por consequncia, qual o SGBD a ser acessado. O componente TSQLQuery responsvel pelo acesso aos dados e nesse componente que o programador insere as expresses SQL. Ambos os componentes abstraem para o implementador detalhes do banco de dados, ou seja, os componentes fazem o acesso DLL enviando as expresses SQL e devolvendo os resultados dessas execues.

4. Padro DAO com DBExpress


O objetivo de definir uma estratgia para utilizao do padro DAO nesse trabalho permitir que as expresses SQL sejam concentradas em classes DataAccessObject, e

no espalhadas pelas janelas como acontece convencionalmente. Pretende-se aqui especificar e explicar como funcionaro as classes DataAccessObject e TransferObject. O papel de DataSource ser desempenhado pelos dois componentes DBExpress comentados na seo anterior. A conexo com o banco desempenhada pelo componente TSQLConnection, e normalmente existe um nico objeto desses na aplicao toda, pois o tempo e a quantidade de recursos alocados para conexo considervel e limitada. Por essa razo, cada classe DataAccessObject receber como parmetro no construtor um objeto TSQLConnection que ser guardado num atributo. Como os componentes visuais so associados com componentes DataSource (classe do pacote DataAccess), e esse componente pode ser associado com componentes TSQLQuery, definiu-se que os mtodos de leitura devem receber como parmetro um objeto TSQLQuery, e popular seu atributo SQL. Com isso, a classe aqui proposta no fornece objetos TransferObject. A figura 2 demonstra um exemplo de um mtodo de leitura de dados de uma tabela chamada Fornecedor.
function TFORNECEDORDADO.SelecionarFornecedor(FQuery : TSQLQuery; Fo_Cod: Variant): TSQLQuery; begin FQuery.SQLConnection := Conecta; FQuery.Close; FQuery.SQL.Clear; FQuery.SQL.Add(Select * From Fornecedor ); FQuery.SQL.Add(Where Fo_Cod= :Fo_Cod ); FQuery.ParamByName(FO_COD).AsString := Fo_Cod; Result := FQuery; end;

Figura 2 Exemplo de mtodo de leitura de dados

Entretanto, para os mtodos de insero, alterao e excluso, definiu-se que devem receber um objeto TransferObject e criar um TSQLQuery dentro do prprio mtodo, mapear o objeto TransferObject para cdigo SQL e executar a expresso. A figura 3 apresenta um exemplo para o mtodo de insero na mesma tabela Fornecedor usada na figura 2. A justificativa dessa estratgia apoiada pelo prprio padro DAO, que define o recebimento de um objeto TransferObject. As alternativas so enviar um parmetro para cada coluna da tabela, ou utilizar atributos na classe DataAccessObject. A primeira alternativa desagrada pela quantidade de parmetros que os mtodos teriam, o que exige lembrar e respeitar a sequncia desses parmetros. A segunda alternativa faria com que a classe DataAccessObject mantivesse os dados, o que vai contrrio responsabilidade dela que administrar o acesso aos dados e no guardar esses dados. A criao do TSQLQuery internamente acontece pelo fato de no existir a necessidade de acomplamento dos componentes visuais com esse componente, uma vez que nenhum componente visual se beneficia de uma expresso de incluso, alterao ou excluso de dados.

procedure TFORNECEDORDAO.Inserir(FORNECEDOR : TFORNECEDOR); var FQuery : TSQLQuery; begin FQuery := TSQLQuery.Create(Nil); try FQuery.SQLConnection := Conecta; FQuery.SQL.Clear; FQuery.SQL.Add('Insert Into FORNECEDOR'); FQuery.SQL.Add('(FO_COD, FO_DSC, FO_DSC_RED, FO_CNPJ, '+ 'FO_INSCR_EST, FO_RUA, FO_CEP, FO_CIDADE, FO_BAIRRO, FO_UF'); FQuery.SQL.Add('Values'); FQuery.SQL.Add('(:FO_COD,:FO_DSC,:FO_DSC_RED, :FO_CNPJ, '+ ':FO_INSCR_EST,:FO_RUA,:FO_CEP,:FO_CIDADE,:FO_BAIRRO,:FO_UF )'); FQuery.ParambyName('FO_COD').AsInteger := FORNECEDOR.FFO_COD; FQuery.ParambyName('FO_DSC').AsString := FORNECEDOR.FFO_DSC; FQuery.ParambyName('FO_DSC_RED').AsString := FORNECEDOR.FFO_DSC_RED; FQuery.ParambyName('FO_CNPJ').AsString := FORNECEDOR.FFO_CNPJ; FQuery.ParambyName('FO_INSCR_EST').AsString := FORNECEDOR.FFO_INSCR_EST; FQuery.ParambyName('FO_RUA').AsString := FORNECEDOR.FFO_RUA; FQuery.ParambyName('FO_CEP').AsString := FORNECEDOR.FFO_CEP; FQuery.ParambyName('FO_CIDADE').AsString := FORNECEDOR.FFO_CIDADE; FQuery.ParambyName('FO_BAIRRO').AsString := FORNECEDOR.FFO_BAIRRO; FQuery.ParambyName('FO_UF').AsString := FORNECEDOR.FFO_UF; FQuery.ExecSQL; finally FreeAndNil(FQuery); end; end;

Figura 3 Exemplo de mtodo para insero

As prximas figuras exemplificam a utilizao desses mtodos numa aplicao real. A figura 4 apresenta dois trechos de cdigo de como seria incluir e buscar fornecedores sem utilizao do padro. As expresses SQL dos componentes QueryInsereFornec e QueryBuscaFornec da figura 4 so atribudas uma nica vez diretamente durante a edio da form. A figura 5 apresenta as mesmas operaes utilizando o padro DAO. Inclusive na figura 5 verifica-se que no mais necessrio o uso do componente QueryInsereFornec.
... With QueryInsereFornec do begin ParamByName('FO_DSC').AsString ParamByName('FO_DSC_RED').AsString ParamByName('FO_CNPJ').AsString ParamByName('FO_INSCR_EST').AsString ExecSQL; ... With QueryBuscaFornec do begin Close; ParamByName('FO_COD').AsInteger Open; ... := := := := edNome.Text; edNomeFantasia.Text; edInscrEst.Text; edCNPJ.Text;

:= strtoint(edCodigo.Text);

Figura 4 Exemplo de cdigo fonte para inserir e buscar fornecedores


... Fornec := TFornecedor.create; Fornec.FO_DSC := edNome.Text; Fornec.FO_DSC_RED := edNomeFantasia.Text; Fornec.FO_CNPJ := edInscrEst.Text; Fornec.FO_INSCR_EST := edCNPJ.Text; FornecDAO.Inserir (Fornec); ... FornecDAO.SelecionarFornecedor(QueryBuscaFornec, strtoint(edCodigo.Text)); QueryBuscaFornec.Open; ...

Figura 5 Exemplo de insero e busca de fornecedores utilizando padro DAO

5. Ferramenta Aplicadora do Padro DAO em Projetos Delphi


A utilizao de padres leva a produtividade devido ao reuso e facilidade na manuteno, e uma vez que a equipe conhece sobre o assunto, eles so facilmente empregados em novas aplicaes. Com o intuito de permitir que aplicaes legadas em Delphi possam ser convertidas para aplicaes que utilizam o padro DAO, foi desenvolvida uma ferramenta que interpreta e altera os projetos substituindo cdigo fonte tanto em arquivos PAS quanto DFM. A ferramenta foi desenvolvida na forma de assistente, isto , cada passo na converso dividida numa pgina e todas contendo um boto para ir prxima fase. O cdigo a ser gerado e as alteraes no projeto acontecem somente no final. As fases na aplicao do padro so as seguintes: 1. identificao do banco de dados: nesse momento o usurio informa qual o banco de dados a ser considerado (a ferramenta suporta somente o Interbase); 2. identificao do local para gerao das classes DAO: aqui informada uma pasta onde a ferramenta gerar as classes DAO; 3. identificao das tabelas a serem aplicadas o padro DAO: baseado no banco de dados informado na fase anterior, a ferramenta apresenta todas as tabelas que pertencem a esse banco, para que o usurio selecione quais so as tabelas que devem ser consideradas na aplicao do padro. Com isso, a ferramenta mapear uma classe DataAccessObject e uma TransferObject relativa a cada tabela. A classe DataAccessObject conter os mtodos para inserir, alterar, excluir e selecionar todos os registros. A classe TransferObject conter um atributo para cada coluna da tabela. As duas classes sero criadas numa nica unit; A figura 6 apresenta a primeira pgina da ferramenta e nela so destacadas as trs primeiras fases do processo. Ao clicar no boto [Gerar classes] o processo continua para as prximas fases 4. configuraes do projeto: nesse momento devem ser informadas a pasta do projeto Delphi a ser analisado e a pasta de destino quando a ferramenta gerar as classes. Na figura 7 est legendado com o nmero 4 a rea onde feita essa configurao; 5. anlise dos arquivos PAS e DFM: essa fase executada pela ferramenta, quando o usurio clica em [Analisar fontes]. Nessa fase a ferramenta analisa cada arquivo do projeto, informado na fase anterior, procurando pelos componentes TSQLQuery. So considerados somente os componentes arrastados para as janelas, ou seja, aqueles que esto no DFM. Quando a ferramenta encontra um componente ele faz a classificao da natureza da operao da expresso SQL (INSERT, UPDATE, DELETE ou SELECT) e a tabela envolvida. A informao da tabela determina a classe DataAccessObject a ser considerada, que deve ser alguma mapeada na fase 3. A expresso SQL base para a criao de um mtodo nessa classe (Inserir, Alterar, Excluir ou Selecionar). Mas antes de cri-lo, verificado se j existe na classe o mtodo. Com isso evita-se mtodos duplicados na classe DataAccessObject. O mtodo

pode ter sido criado em dois momentos: na fase 3 ou nessa mesma fase, quando encontrou a expresso SQL em uma unit j analisada. As expresses SELECT que envolvem mais de uma tabela fazem com que a ferramenta mapeie uma nova classe DataAccessObject sendo batizada com a unio do nome de todas as tabelas envolvidas na expresso. Por exemplo, uma juno entre as tabelas Produto e Pedido gera uma classe ProdutoPedido com um mtodo Selecionar contendo essa expresso SELECT de juno.

1 2

Figura 6 Janela da ferramenta com as fases 1, 2 e 3

6. nomear mtodos das classes DataAccessObject: aps a anlise de todos os arquivos so apresentados ao usurio todas as classes que sero geradas, e mtodos identificados para cada classe, junto da expresso SQL que originou a necessidade do mtodo e as units em que ela foi identificada. Nessa fase o usurio pode alterar o nome do mtodo a ser gerado, pois a regra de batismo da ferramenta baseada na natureza da operao (InserirXXX, AlterarXXX, ExcluirXXX e SelecionarXXX, onde XXX o nome da tabela) e mais um nmero sequencial. Por exemplo, a ferramenta pode ter detectado vrios comandos SELECT (o que bem natural) para a tabela Pedido e o nome dos mtodos seriam SelecionarPedido1, SelecionarPedido2 e assim por diante. Esses nomes no so muito sugestivos sobre o objetivo do comando de seleo, e por essa razo a ferramenta permite que os mtodos sejam rebatizados. A figura 7 ilustra atravs de uma legenda a fase 6. A figura 8 mostra a janela onde pode se alterar o nome de um mtodo;

4 6

Figura 7 Janela da ferramenta com as fases 4, 5, 6 e 7

7. gerao do cdigo e substituio dos arquivos PAS e DFM: essa a ltima fase do processo. Nos arquivos DFM so eliminadas as expresses SQL dos componentes TSQLQuery e no arquivo PAS criado um mtodo FormCreate (se ainda no existia) com a inicializao das expresses atravs da classe DataAccessObject. Ainda nos os arquivos PAS, as linhas de cdigo com as expresses SQL so eliminadas e substitudas por chamadas aos mtodos das classes DataAccessObject, da forma como j foram ilustrados nas figuras 4 e 5. Aps a execuo dessas fases o novo projeto estar funcional e utilizando o padro DAO. Qualquer mudana no projeto do banco de dados e que exiga alteraes no projeto Delphi devem ser feitas diretamente nas classes DataAccesObject.

Figura 8 Janela para alterao do nome do mtodo

6. Concluses
A aplicao de padres de projeto eleva o nvel de qualidade no produto final. Aps experimentar a ferramenta descrita nesse trabalho numa aplicao real percebeu-se que o cdigo gerado permite facilidade em sua manuteno, pois eliminou a redundncia, e concentrou todo o cdigo SQL em classes especficas. Devido forma como os programadores Delphi esto habituados a desenvolverem as aplicaes atravs de usar muito componentes, sugere-se que qualquer nova tcnica ou idia para melhorar o desenvolvimento de aplicaes nessa linguagem inclua a utilizao de componentes. Outro ponto importante a ressaltar, que a prtica de novas tcnicas e paradigmas de desenvolvimento considerem a aplicaes legadas. Existe muito cdigo no Brasil produzido com Delphi, inclusive com verses anteriores 7.0, e um fator motivante de novidades que sejam compatveis com o que j faa parte do portflio da equipe de desenvolvimento. O texto apresentado nesse artigo levou em considerao esses dois pontos: props idias para a adoo do padro de projeto DAO usando componentes DBExpress, e descreveu uma ferramenta para que aplicaes legadas possam usufruir dessas idias.

Referncias
Ace, I. (2005) Analisando o Microsoft PetShop 3.0. So Paulo. Disponvel em: <http://www.projetando.net/Sections/ViewArticle.aspx?ArticleID=14>. Acesso em: 07 abr. 2007. Borland Software Corporation. (2005) Borland Delphi for Microsoft Windows: help. Version 7.10.3077. Fowler, M. (2006) Padres de arquitetura de aplicaes corporativas. Gamma, E. et al (2000) Padres de projeto: solues reutilizveis de software orientado a objetos. Shalloway, A.; Trott, J. (2004) Explicando padres de projeto: uma nova perspectiva em projeto orientado a objeto. Sun. (2007) Core J2EE patterns: data access object. Disponvel em: <http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html>. Acesso em: 15 abr. 2007 Valente, L. (2003) Design patterns: padres para projetos.. 24 f. Dissertao (Mestrado em Computao)-Universidade Federal Fluminense, Niteri. Disponvel em: <http://www.ic.uff.br/~lvalente/docs/DesignPatterns_Texto.pdf>. Acesso em: 07 abr. 2007.

Você também pode gostar