Sunday, March 18, 2007 6:50 PM

 

Outro dia respondi uma pergunta no fórum MSDN sobre desenvolvimento em camadas. Meu único conselho para o rapaz foi isolar os objetos de acesso a dados na camada de dados. Para mim toda referência a biblioteca System.Data fora da camada de dados deveria ser tratada como um code smell.

No dia seguinte outro desenvolvedor respondeu minha resposta com a seguinte questão:

"No page-load da grid chamo um método de popular grid que se encontra na minha camada de negócios, essa por sua vez irá receber os parâmetros necessário, validar informações, montar a query e enviar para a camada de Dados executar. A camada de dados me retornar um conjunto de dados que é recebido pela camada de negócio que então popular a grid.

Neste processo como deixar a camada de negócio não enxergar o que a camada de dados me retornou? Teria que transformar o datareader/dataset/datatable em alguma outra coisa? De repente dizer diretamente que gv.datasource = CamadaNegocio.recuperaPedidos()."

Como acho que outras pessoas devem ter este mesmo “problema”, achei que a resposta para o questionamento merecia um post no meu blog.

A resposta para esta pergunta é simples: existem diversas formas de evitar a manipulação de objetos de dados (residentes da biblioteca System.Data) em sua camada de UI, aqui vão duas:

Não utilizar a funcionalidade de data binding do ASP.Net. Você pode criar seu próprio mecanismo de binding, utilizar algum framework que implementa data binding, como o Monorail ou implementar sua interface utilizando o Model View Presenter pattern em sua versão Passive view.

Utilizar a funcionalidade de object datasource do .Net 2.0 e fazer o data binding com seus próprios objetos ao invés de utilizar as estruturas de dados do ADO.Net.

Mas neste momento não quero descrever a solução, mas sim ir um pouco mais a fundo no problema. Afinal antes de termos uma solução temos que ter um problema. (Já estou eu criando problemas para quem já tem tantos outros...)

Em dos primeiros livros que li sobre OO aplicado na prática o autor sugeria a utilização de uma estrutura de dados própria para a comunicação entre as camadas de uma aplicação. A coisa era simples, nada mais que strings com separadores e um parser para ler e construir as strings. O objetivo dele era abstrair toda e qualquer tecnologia da comunicação de dados, desta forma a evolução de sua aplicação seria mais fácil. Achei aquilo interessante, mas um pouco exagerado.

Quando eu mostrava esta solução para outros desenvolvedores só faltavam chamar a ambulância do manicômio. Para que isto??!! É só passar um recordset, era a resposta padrão. Estávamos no início do reinado do ADO, o mundo finalmente tinha descoberto a API definitiva para acesso e manipulação de dados...

Antes disto tínhamos o DAO, depois disto tivemos o ADO.Net, ADO.Net 2.0...O Linq e suas variações começam a surgir no horizonte...E ainda temos as soluções de ORM correndo por fora...

Isto tudo em um espaço de tempo de 6 anos, no máximo! Para cada desenvolvedor que adotou uma destas API’s e a espalhou ao longo das camadas, como por exemplo uma página ASP lendo dados de um recorset, temos hoje uma aplicação com seus dias contados. Eu certamente tenho algumas destas na minha conta :)

Aplicações de negócios são essencialmente movidas de acesso a dados, é de se esperar que estas API’s evoluam, melhorando performance e trazendo novas funcionalidades. Não há nada de errado com isto, pelo contrário, isto é muito bem-vindo (Eu não tenho nenhuma saudade do DAO)

Mas justamente para que a sua aplicação possa se aproveitar destas evoluções e garantir uma vida longa é necessário abstrair a utilização destas API’s e isolá-las na camada de dados. Desta forma a migração e evolução do acesso a dados se dá forma mais “tranquuml;ila”.

Baixo acoplamento é uma característica sempre desejada. Principalmente se estamos falando de componentes de terceiros e de tecnologia tão voláteis, como é o caso do acesso a dados.

Agora sim seguem algumas referências para solucionar o problema:

Model View Presenter:

Monorail:

ASP.Net data binding:

Comments

At 3/21/2007 5:50 PM, blogs.msdn.com said:

#  Isolando o Acesso a Dados

At 7/30/2007 1:22 PM, Eder Willian said:

# re: Isolando camadas da aplicação

Eduardo, estou começando agora a entender e desenvolver em asp.net e tenho várias dúvidas justamente sobre arquitetura das camadas da aplicação.

Voce tem interesse em prestar uma consultoria ou sabe onde encontro algum exemplo básico de como separar as camadas para ganhar em produtividade no desenvolvimento?

Eder
At 8/2/2007 8:38 AM, Eduardo Miranda said:

# re: Isolando camadas da aplicação

Eder,

Obrigado pela confiança, mas atualmente não faço consultoria, sou funcionário de uma empresa de tecnologia.

Existem vários exemplos, com vários de níveis de complexidade. É preciso identificar qual a sua necessidade e escolher o melhor caminho.

A Petshop 4 é um bom exemplo de uma solução simples, que separa as camadas. Existem alguns problemas em sua arquitetura, que podem ser resolvidos facilmente.

O projeto SubSonic também oferece alguns exemplos interessante, bem desenhados.

Para uma solução muito mais robusto pode ser visto no livro Domain-Driven Design, do Eric Evans. Existe uma mini-versão grátis do livro disponível para download.

Além disso sugiro que você estude um pouco os design patterns específicos de cada camada. Com eles você pode montar sua própria arquitetura. Por exemplo, para a camada de interface o MVP (Model View Presenter) tem sido uma escolha comum para ASP.Net. Na camada de dados você pode optar por DAO, que é aplicado na PetShop, por active record, aplicado pelo SubSonic, ou pelo Repository, aplicado pelo Eric Evans em seu DDD.

Boa sorte e continue buscando conhecer cada mais, para fazer cada melhor.
At 7/14/2009 3:08 PM, Luiz Oliveira said:

# re: Isolando camadas da aplicação

Prezado colega, boa tarde. Peço desculpas por insistir neste assunto, e perdoe a minha igonorancia sobre alguns temas, pois sou oriundo da era dos RecordSet desconectados, onde um loop resolvia o problema de carga de controles.
Ao ler seu post, voce nos sugere isolar completamente a camada de dados das demais, e realmente a mim parece uma boa idéia. O problema é que ainda não consegui compreender como fazer...
Ainda no exemplo do GridView, vc sugere não utilizar o Binding do controle e sequer utilizar a System.Data na apresentação. Assim, seria necessario desenvolver uma outra forma de carregar tal controle, através de um framework (Monorail, por exemplo) ou realizar o binding através do ObjectDataSource, personalizando-o...
Desculpe novamente, mas a impressão que tenho é de estar "reinventando a roda", pois se já tenho um recurso disponível de de utilização imediata (no caso do gridview, seu próprio DataSource e DataBind), não consigo compreender a utilização de uma outra ferramenta (MonoRail) ou reescrever o binding...

Agradeço sua paciência e disposição em nos ajudar e novamente desculpe minha ignorância se não compreendi direito seu post.


Atenciosamente,
Luiz Oliveira.
At 7/18/2009 3:42 PM, Eduardo Miranda said:

# re: Isolando camadas da aplicação

Caro Luiz,

Neste post parto do princípio que uma boa separação em camadas é benéfica para o seu contexto. Não tinha o interesse de apresentar as vantagens desta prática, pois existe material abundante sobre o assunto na internet.

Dado que queremos separar as camadas da aplicação, utilizar objetos da biblioteca System.Data em sua camada de UI é um claro sinal de que a separação não está correta, concorda?

Dentre as opções que sugeri (não são as únicas) falei desde utilizar o object datasource, que está pronto e disponível no .NET framework, até criar seu próprio binding. É claro que espero que todos usem seu bom senso, analisem o seu próprio problema, e escolham a solução que melhor lhe atende.

Mas vamos deixar algo muito claro, se vc quiser utilizar o object datasource não é necessário implementar uma linha de código a mais do que outro tipo de datasource.

Sugiro que você pesquise um pouco as referências que coloquei ao final do artigo.
Post Comment
Title *
Name *
Email (never displayed)
Website
Comment * (Allowed tags: blockquote, a, strong, em, p, u, strike, super, sub, code)  
Please add 3 and 4 and type the answer here: