VB .NET - Criando uma aplicação em camadas
Lá vou eu em mais um artigo sobre como criar uma aplicação em camadas, no nosso exemplo em 3 camadas. Parece que eu não me canso do assunto não é mesmo ???
E parece que apesar de todo material existente sobre este assunto as dúvidas persistem, principalmente para quem esta iniciando.
Então este artigo é dirigido aos iniciantes e por isso eu vou usar uma linguagem bem simples em um exemplo bem simples usando figuras para ilustrar os conceitos.
Vamos começar definindo o que será preciso para acompanhar o artigo:
Começando pelo começo...
O significa criar uma aplicação em camadas ?
Quando você acessa a página do seu banco na internet esta usando uma aplicação que possui uma tela de apresentação onde você, usuário, recebe e entra com as informações.
- Quando você faz o login na sua
conta acessando a página do seu banco na internet existe uma
interface onde você informa seu login e senha.
- Quando você submete esta informação a aplicação aplica as
regras de negócios para verificar se seu login e senha são
válidos.
- Para isso ele consulta um cadastro de informações, que esta
em um banco de dados, e verifica se o que o usuário digitou
corresponde ao que esta no cadastro;
Com esse exemplo bem simples podemos perceber que temos 3 partes distintas atuando:
A figura abaixo procura mostrar de forma resumida esses 3 componentes identificando e nomeando cada um deles;
Podemo identificar as
seguintes camadas:
|
Embora para o cliente tudo seja apenas uma única aplicação para o desenvolvedor (você), criar uma aplicação em camadas significa desenvolver separadamente cada um dos componentes identificados no exemplo acima de forma a facilitar a manutenção e ganhar produtividade.
Chama-se a isso uma aplicação com arquitetura em 3 camadas. (Podemos ter aplicações em n-camadas)
Resumindo:
A arquitetura em 3 camadas é uma
arquitetura cliente servidor na qual a interface do usuário,
processos de negócios e armazenamento de dados são
desenvolvidos e mantidos em módulos independentes, ou em
plataforma separadas.
Basicamente existem 3 camadas :
- Camada de
apresentação - User Interface (UI)
- Camada de Negócios - Business Logic Layer (BLL)
- Camada de Acesso a dados - Data Access Layer (DAL)
Cada camada pode ser desenvolvida e testada separadamente.
Ao realizar a separação das camadas de uma aplicação podemos fazer uma separação física ou uma separação lógica das camadas:
Na figura abaixo vemos um exemplo de projeto usando a física e outro usando a separação lógica das camadas:
Exemplo de projeto com
arquitetura em 3 camadas usando a separação física das
camadas. Temos 3 projetos distintos em uma solução. |
||
Exemplo de projeto com
arquitetura em 3 camadas usando a separação lógica das
camadas. Temos 1 projeto contendo 3 pastas onde estão os componentes de cada camada em uma solução. Podemos também ter as classes representando cada camada juntas no projeto: |
Quais são os componentes de cada camada ?
De forma bem simples geralmente temos:
1 - Camada de
Apresentação (Presentation Tier ou UI) - Formulários e Controles de
Usuário 2 - Camada de Negócios (Business Tier) (BLL) - Classes - Regras de
Negócio, Objetos de negócio 3- Camada de Acesso a Dados (DAL) - Classes - Regras de Acesso a dados, métodos, etc. |
Nota: Cabe aqui um esclarecimento para que não haja confusão na utilização dos termos Tier e Layer. Em geral podemos traduzir tais termos como camadas, mas o termo Tier refere-se a camada física enquanto que o termo Layer refere-se a camada lógica.
Criando uma aplicação em 3 camadas na prática
Para que fique bem claro toda a teoria vamos criar uma aplicação em 3 camadas usando a linguagem VB .NET.
Como o artigo é para iniciantes eu vou simplificar ao máximo para que o entendimento não seja prejudicado.
Vamos criar uma aplicação para acessar e dar manutenção em cadastro de alunos armazenado na tabela Clientes do banco de dados Microsoft Access Cadastro.mdb.
Obs: Escolhi um banco de dados Microsoft Access por ser mais simples de trabalhar e distribuir mas em aplicações comerciais aconselha-se usar um verdadeiro RDMS como SQL Server, MySQL, Oracle, DB2, etc.
Vamos adotar a arquitetura em 3 camadas usando a separação lógica onde teremos a seguinte estrutura:
Abra o Visual Basic 2010 Express Edition e no menu File clique em New Project e selecione o template Windows Forms Application e informe o nome : ProjetoTresCamadas-SeparacaoLogica;
Será criado um projeto contendo um formulário form1.vb. Selecione o formulário form1.vb e altere o seu nome para Camada1_frmApresentacao;
No menu Project clique em Add Class e selecione o template Class informando o nome Camada2_Negocio;
No menu Project clique em Add Class e selecione o template Class informando o nome Camada3_AcessoDados;
Ao final você deverá ver na janela Solution Explorer uma solução contendo um projeto com a seguinte estrutura:
O fluxo da informação entre as camadas é mostrada na figura a seguir:
Vemos que a camada de apresentação (UI) chama a camada de Negócios (BLL) que chama a camada de Acesso a dados (DAL) que acessa o banco de dados e retorna a informação.
Definindo o código da camada de acesso aos dados - DAL
A camada de acesso a dados é uma classe que terá como responsabilidade acessar o banco de dados Cadastro.mdb e realizar operações de consulta e persistência como alterar, incluir e excluir registros. Essas operações são conhecidas como CRUD - Create, Retrieve, Update e Delete.
CRUD
(acrônimo de Create, Retrieve,
Update e Delete em língua Inglesa) para as quatro operações
básicas utilizadas em bancos de dados relacionais(RDBMS)
ou em interface para usuários para criação, consulta,
atualização e destruição de dados. Outros acrônimos podem ser usadas para definir as mesmas operações:
|
Temos muitas opções para definir o código da camada de acesso a dados, podemos usar DataSets tipados, LINQ to SQL, Entity Framework, NHibernate, etc., mas para quem esta iniciando é bom começar pela então vamos usar ADO .NET.
A ADO.NET consiste em um conjunto de classes definidas pela plata forma .NET framework que podem ser utilizadas para acessar e persistir dados em um banco de dados relacional.
A primeira coisa a fazer para criar uma conexão ADO.NET com uma fonte de dados é escolher o provedor dados .NET . Cada provedor fornece classes que permitem realizar as seguintes tarefas :
O que é um provedor dados .NET ( .NET data providers ) ?
Os provedores de dados .NET são um conjunto de componentes incluídos na arquitetura ADO.NET que permitem a comunicação entre a fonte de dados e o componente , um XML , WEB Service ou uma aplicação.
Quais os tipos de provedores de dados disponíveis ?
Os principais provedores de dados disponíveis com o .NET Framework atualmente são :
Em nosso exemplo vamos usar o provedor OLE DB .NET Data Provider.
O provedor de dados OLE DB .NET utiliza o OLE DB nativo e a interoperabilidade COM para realizar a conexão e a comunicação com uma fonte de dados. Você vai ter que usar um provedor OLE DB ao utilizar este provedor , indicando-o em uma string de conexão.
Ex: "Provider=Microsoft.Jet.OLEB.4.0;Data Source=Banco_Dados.mdb"
Vamos abrir o arquivo Camada3_AcessoDados.vb e iniciar com a declaração do namespace para acessar o banco de dados Microsoft Access:
Imports System.Data.OleDb
A seguir , logo a após a declaração da classe vamos definir a variável cnn que será usada para tratar a conexão com o banco de dados:
Private cnn As OleDbConnection
Devemos declarar também a string de conexão definindo o provedor , o caminho e o nome do banco de dados:
Dim strConexao As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\dados\Cadastro.mdb;"
Em seguida vamos criar uma função chamada getAlunos() que vai receber como parâmetro uma string e que vai devolver um objeto DataTable.
As
Funções ou Function - são rotinas que realizam tarefas
e que retornam valores. No caso das funções usamos
a palavra-chave : Function seguida do nome da função e da
relação dos parâmetros e terminamos com a
palavra-chave : End Function. No código da função usamos também a palavra-chave : Return que irá retornar o valor da função. Assim temos:
|
A seguir temos o código da função getAlunos() que irá receber uma string referente a um comando SQL e que irá retornar um DataTable com as informações dos Clientes:
Public Function getAlunos(ByVal sql As String) As DataTable Try Dim cnn As OleDbConnection = New OleDbConnection(strConexao) Dim da As OleDbDataAdapter = New OleDbDataAdapter(sql, strConexao) Dim dt As DataTable = New DataTable da.Fill(dt) Return dt Catch ex As Exception Throw New Exception("Erro ao acessar os dados : " & ex.Message) Finally If ConnectionState.Open Then cnn.Close() End If End Try End Function |
Observe que o código da função esta contido no interior de um bloco Try/Catch/Finally usado para tratamento de erros.
Capturar e tratar
erros(exceções) é uma das tarefas obrigatórias para
todo o programador. O VB.NET trouxe uma novidade que nos
auxilia no tratamento de erros : o bloco try-catch-finally.
(Se você conhece Java esta em casa...). O bloco try-catch-finally é usado para envolver o código onde existe a possibilidade de uma exceção/erro ocorrer. Um bloco try-catch-finally é constituído das seguintes seções :
Obs: O VB.NET ainda mantém , por questões de compatibilidade , a sintaxe : "On Error Goto" e você ainda pode usá-la mas prefira usar a estrutura try-catch. A estrutura try-catch-finally é mais poderosa que a sintaxe anterior pois além de permitir a você fazer um aninhamento de vários tratamentos de erros na mesma estrutura , torna o código mais fácil de ler e manter. |
Vamos entender o código usado:
1- cnn = New OleDbConnection(strConexao)
Criamos uma conexão usando a string de conexão - strConexao - que foi definida no início da classe.
O objeto Connection têm a função de gerar uma conexão com uma fonte de dados sendo portanto o objeto fundamental no acesso a dados.
Para estabelecer uma conexão com uma fonte de dados o objeto Connection usa a propriedade ConnectionString que é a string de conexão que deverá ser informada para que a conexão seja efetivamente aberta.
Após realizada a conexão com a fonte de dados podemos usar objetos para receber e enviar dados para a fonte de dados , dentre estes objetos podemos citar : Command e Adapter;
2- Dim
da As OleDbDataAdapter = New OleDbDataAdapter(sql, strConexao)
O DataAdapter usado é o OledbDataAdapter e
criamos um novo Adapter passando a instrução SQL e a string de
conexão:
A função do DataAdapter é a seguinte :
Não pense que o serviço do DataAdapter pare por ai ; quando os dados que foram alterados no DataSet precisam voltar para o banco de dados para atualizar a fonte de dados , novamente o DataAdapter atua :
3- Dim
dt As DataTable = New DataTable
Definimos um
objeto DataTable para ser preenchido e retornado com as
informações dos clientes.
Os objetos DataTable são usados para representar e tratar estas
tabelas ; além disto podemos criar relacionamentos entres estas
tabelas através de objetos DataRelation.
Um objeto DataTable representa uma ou mais tabelas de dados em memória. Os objetos DataTable estão contidos no objeto DataSet e/ou DataView.
4-
da.Fill(dt)
Preenchemos o
DataTable usando o método Fill.
Para acessar o banco de dados , executar o comando SQL via DataAdapter , trazer os dados e preencher o DataSet usamos o método Fill .
O método Fill retorna a linhas de uma fonte de dados usando a declaração SELECT definida por uma propriedade SelectCommand associada. O objeto Connection associado com a declaração SELECT precisa ser válido mas não precisa ser aberto. Se a conexão for fechada antes de você chamar o método Fill ela será aberta para que os dados possam ser retornados e em seguida fechada novamente. Se a conexão estiver aberta ela permanecerá aberta após o uso do método Fill.
O método Fill então irá incluir as linhas ao objeto DataTable de destino , criando o objeto DataTable , se ele ainda não tiver sido criado. Ao criar o objeto DataTable a operação Fill normalmente cria somente colunas com medadata.
5-
Return dt
retornamos um objeto
DataTable preenchido.
Se ocorrer alguma exceção durante a execução do código acima será lançada uma exceção:
6- Throw New Exception("Erro ao acessar os dados : " & ex.Message)
A exceção será lançada para a camada de negócios que chamou a função que por sua vez deverá repassá-la a camada de apresentação para ser exibida ao usuário.
7- No interior do bloco Try/Catch/Finally temos o código que verifica se a conexão esta aberto e a fecha. A cláusula Finally garante que o código no seu interior seja executada mesmo ocorrendo uma exceção portanto a conexão sempre será fechada.
If
ConnectionState.Open Then
cnn.Close()
End If
O código completo da classe Camada3_AcessoDados pode ser visto a seguir:
Imports System.Data.OleDb Public Class Camada3_AcessoDados Private cnn As OleDbConnection Dim strConexao As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\dados\Cadastro.mdb;" Public Function getAlunos(ByVal sql As String) As DataTable Try cnn = New OleDbConnection(strConexao) Dim da As OleDbDataAdapter = New OleDbDataAdapter(sql, strConexao) Dim dt As DataTable = New DataTable da.Fill(dt) Return dt Catch ex As Exception Throw New Exception("Erro ao acessar os dados : " & ex.Message) Finally If ConnectionState.Open Then cnn.Close() End If End Try End Function End Class |
Definindo o código da camada de negócios - BLL
É na camada de negócios que se localizam as regras do negócio e da validação dessas regras. (Existem validações feitas na camada de apresentação mas refere-se a validações de dados entrados pelo usuário apenas).
Então, com uma camada de negócios (BLL) podemos efetuar efetuar uma validação de regra de negócio e em seguida passar os objetos para a camada de apresentação.
Como nosso exemplo é muito simples vamos apenas definir a chamada a camada de acesso a dados conforme o código a seguir:
Imports
ProjetoTresCamadas_SeparacaoLogica.Camada3_AcessoDados Public Class Camada2_Negocio Public Function
getTodosAlunos() As DataTable End Class |
Definindo o código da camada de apresentação - UI
Abaixo vemos o código do evento Load do formulário que utiliza a camada de negócios para acessar os dados e exibi-los no controle DataGridView
Imports
ProjetoTresCamadas_SeparacaoLogica.Camada2_Negocio Public Class Camada1_frmApresentacao
Private Sub Camada1_frmApresentacao_Load(ByVal
sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub End Class |
Executando o projeto iremos obter:
Dessa forma eu quis mostrar , sem complicar, como é fácil usar a arquitetura em camadas em sua aplicação. Um pouco de disciplina e esforço no início o compensarão com menos esforço e mais tranqüilidade no futuro.
Pegue o projeto completo aqui : ProjetoTresCamadas-SeparacaoLogica.zip
Eu sei é apenas VB .NET, mas eu gosto...
"Eu sou a videira verdadeira e meu Pai é o lavrador. Toda a vara em mim que não dá fruto, a tira; e limpa toda aquela que dá fruto, para que dê mais fruto." (João 15:1-2)
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#