VB .NET - 7 passos para criar uma aplicação em 3 Camadas - Parte 3
Na segunda parte deste artigo iniciamos a definição das camadas da nossa solução iniciando com a camada DTO e a camada de acesso a dados. Continuando a nossa caminhada cujo objetivo é criar uma aplicação em camadas usando o VB .NET.
Iremos agora continuar a definição das camadas da nossa aplicação desta vez abordando a camada de negócios - CamadaBLL - que é responsável pelas regras de negócio do nosso domínio e onde iremos efetuar as validações.
O objetivo da camada de negócios é implementar a lógica da aplicação, expondo esta lógica para a camada de apresentação e outras aplicações, e também acessar a camada de acesso a dados.
Passo 6 - Definindo as classes do nosso domínio na camada de negócio - CamadaBLL
Como ja escrevi nosso modelo é muito simples e estamos usando o padrão DAO para implementar as funcionalidades da nossa solução. Nada muito sofisticado mas funcional seguindo o padrão KISS - Keept Simple Stupid. (é um princípio que defende que toda a complicação desnecessária deve ser evitada. Então se o jeito simples é o certo, por que complicamos ? Por pura falta de competência e preguiça. Simples não é sinônimo de fácil.)
Seguindo este padrão vamos agora criar as classes da camada de negócio - CamadaBLL - onde para cada classe do nosso domínio teremos uma classe de negócio relacionada.
Vamos então definir as classes e nestas classes vamos definir os métodos que acessam a camada de acesso a dados. Eu não estou realizando nenhuma validação nesta camada para deixar o exemplo mais limpo e fácil de entender mas qualquer validação de negócio deverá ser feita nesta camada.
1- Criando a classe ClasseBLL
Clique com o botão direito do mouse sobre o projeto CamadaBLL e selecione Add->Class;
Selecione o template Class e informe o nome ClasseBLL.vb e clique no botão Add;
A seguir vamos definir o código abaixo nesta classe:
Imports CamadaDTO Imports CamadaDAL Public Class ClasseBLL Public Function GetTodasClasses() As List(Of Classe) Dim db As New ClasseDAL Return db.GetClasses() End Function Public Function GetClassePorCodigo(ByVal _CodigoClasse As Integer) As Classe Dim db As New ClasseDAL Return db.GetClassePorId(_CodigoClasse) End Function Public Function Salvar(ByVal cls As Classe) Dim db As New ClasseDAL Return db.Salva(cls) End Function Public Function DeletarClasse(ByVal _CodigoClasse As Integer) Dim db As New ClasseDAL Return db.DeletaClasse(_CodigoClasse) End Function End Class |
A classe ClasseBLL
possui os métodos:
Esta
classe esta apenas usando os métodos criados para |
2- Criando a classe AlunosBLL
Clique com o botão direito do mouse sobre o projeto CamadaBLL e selecione Add->Class;
Selecione o template Class e informe o nome AlunosBLL.vb e clique no botão Add;
A seguir vamos definir o código abaixo nesta classe:
Imports CamadaDTO Imports CamadaDAL Public Class AlunosBLL Public Function GetTodosAlunos() As List(Of Aluno) Dim db As New AlunosDAL Return db.GetAlunos End Function Public Function GetAlunosPorCodigo(ByVal _alunoId As Integer) As Aluno Dim db As New AlunosDAL Return db.GetAlunoPorId(_alunoId) End Function Public Function GetAlunosPorClasse(ByVal _classeId As Integer) Dim db As New AlunosDAL Return db.GetAlunosPorClasse(_classeId) End Function Public Function SalvaAluno(ByVal _aluno As Aluno) Dim db As New AlunosDAL Return db.SalvaAluno(_aluno) End Function Public Function DeletaAluno(ByVal _alunoId As Integer) Dim db As New AlunosDAL Return db.DeletaAlunoPorId(_alunoId) End Function End Class |
A classe AlunosBLL
possui os métodos:
Esta
classe esta apenas usando os métodos criados para |
As duas classes definidas nesta camada atuam da mesma forma criando uma instância da camada de acesso a dados e usando o método definido para realização da operação.
As validações de negócio devem ser realizadas nesta camada. Isso não esta sendo feito neste exemplo pela simplicidade do projeto.
Passo 7 - Definindo a camada de apresentação - CamadaWin
Vamos agora definir a camada de apresentação onde criaremos um projeto Windows Forms para permitir que o usuário gerencie as classes e os alunos realizando as seguintes operações:
Meu objetivo será mostrar que na camada de apresentação deveremos tratar apenas da apresentação e tratamento das informações pois a lógica do negócio e a persistência dos dados estão em camadas separadas. Dessa forma a camada de apresentação não deve saber nada sobre lógica de negócios nem sobre persistência de dados.
A camada de apresentação para atualizar as informações irá usar os serviços da camada de acesso aos dados via camada de negócios, realizando nesta as validações pertinentes.
No formulário form1.vb que foi criado por padrão vamos definir o leiaute conforme mostra a figura abaixo:
Controles principais do
formulário: GroupBox - grpNovaClasse - Text = Classes
GroupBox - grpAlunos - Text = Alunos
ErrorProvider - ErrorProvider1
|
Vamos declarar a utilização dos namespaces
Imports
CamadaDTO
Imports CamadaBLL
Isso é necessário pois precisamos acessar os métodos da camada de negócios e os objetos na camada DTO.
Precisamos definir uma enumeração para declarar qual a ação que desejamos realizar. A seguir temos a enumeração FlagAcao que define 3 tipos de operação: Insert, Update, Delete e NoAction:
Public Enum FlagAction Insert = 1 Update = 2 Delete = 3 NoAction = 0 End Enum |
No formulário vamos declarar as variáveis para tratar as classes Aluno e Classe:
Private _alunos As List(Of Aluno)
Private _aluno As Aluno
Private _classe As Classe
Private _classes As List(Of Classe)
Esses objetos permitirão acessar e obter informações sobre alunos e classes.
No evento Load do formulário form1.vb vamos carregar a combobox cboClasses e o DataGridView dgvAlunos com as informações das classes e alunos:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load carregaCombo() carregaGrid(cboClasses.SelectedValue) End Sub |
O código do procedimento carregaCombo() é o seguinte:
Sub carregaCombo() Dim clsBLL As New ClasseBLL _classes = clsBLL.GetTodasClasses With cboClasses .DataSource = _classes .DisplayMember = "NomeClasse" .ValueMember = "ClasseId" End With End Sub |
O código acessa o método GetTodasClasses da camada de negócios e preenche o combobox com as classes.
O código do procedimento carregaGrid() é o seguinte:
Sub carregaGrid(ByVal classeID As Integer) Dim alnBLL As New AlunosBLL _alunos = alnBLL.GetAlunosPorClasse(classeID) With dgvAlunos .DataSource = _alunos .ColumnHeadersVisible = True .ColumnHeadersDefaultCellStyle.ForeColor = Color.BurlyWood .Columns.Item("ClasseId").Visible = False .Columns.Item("AlunoId").HeaderText = "Codigo do Aluno" .Columns.Item("NomeAluno").HeaderText = "Nome do Aluno" .Columns.Item("Acao").Visible = False End With End Sub |
O código acessa o método GetAlunosPorClasse() passando o código da classe e forma a obter e exibir os alunos de acordo com a classe selecionada.
No evento SelectedIndexChanged da combobox cboClasses temos o código que obtém as classes e conforme a alteração da classe selecionada carrega e atualiza o datagridview com os alunos pertencentes à classe selecionada:
Private Sub cboClasses_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboClasses.SelectedIndexChanged If cboClasses.SelectedIndex = -1 Then Exit Sub Dim cls As Classe Dim clsBLL As New ClasseBLL cls = clsBLL.GetClassePorCodigo(cboClasses.SelectedIndex + 1) If Not IsNothing(cls) Then carregaGrid(cls.ClasseId) Me.txtNovaClasse.Text = cls.NomeClasse End If End Sub |
No evento Click do botão nova classe apenas preparamos a interface para incluir uma nova classe ou cancelar a operação:
Private Sub btnNovaClasse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNovaClasse.Click If btnNovaClasse.Text = "Nova Classe" Then btnNovaClasse.Text = "Cancelar" btnSalvarClasse.Enabled = True Me.txtNovaClasse.Text = "" Me.cboClasses.SelectedIndex = -1 grpNovaClasse.Text = "Informe uma nova Classe" grpNovaClasse.BackColor = Color.MintCream grpAlunos.Visible = True grpAlunos.Enabled = False Me.txtNovaClasse.Focus() ElseIf btnNovaClasse.Text = "Cancelar" Then grpNovaClasse.BackColor = Color.Pink grpAlunos.Visible = True grpAlunos.Enabled = True btnNovaClasse.Text = "Nova Classe" End If End Sub |
No evento Click do botão Salvar chamamos o procedimento SalvarClasse():
Private Sub btnSalvarClasse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvarClasse.Click SalvarClasse() End Sub |
O procedimento SalvarClasse() realizar a inclusão de uma nova classe ou atualização de uma classe existente:
Sub SalvarClasse() Dim bln As Boolean Dim clsBLL As New ClasseBLL Dim cls As New Classe If txtNovaClasse.Text = String.Empty Or txtNovaClasse.Text.Length < 5 Then MsgBox("Informe o nome da nova classe (minímo 5 caracteres).") txtNovaClasse.Focus() Return End If cls.NomeClasse = Me.txtNovaClasse.Text.Trim If cboClasses.SelectedIndex = -1 Then cls.Acao = FlagAcao.Insert Else cls.ClasseId = cboClasses.SelectedValue cls.Acao = FlagAcao.Update End If bln = clsBLL.Salvar(cls) If bln Then MessageBox.Show("Dados Atualizados com sucesso !") If cboClasses.SelectedIndex = -1 Then carregaCombo() cboClasses.SelectedIndex = 0 End If Refresh(cboClasses.SelectedIndex) grpNovaClasse.Visible = True grpAlunos.Enabled = True btnSalvarClasse.Enabled = False Else MessageBox.Show("Ocorreu um erro ao atualizar os dados !!") btnSalvarClasse.Enabled = False End If End Sub |
No código do evento Click do botão Salvar (grpAlunos) verificamos se existe uma classe selecionada e um nome de aluno informado para chamar o procedimento SalvarAluno():
Private Sub btnSalvarAluno_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvarAluno.Click ErrorProvider1.Clear() If cboClasses.SelectedIndex = -1 Then ErrorProvider1.SetError(Me.cboClasses, "Selecione uma Classe!!") Exit Sub End If If Me.txtNovoAluno.Text.Trim() = "" Then ErrorProvider1.SetError(Me.txtNovoAluno, "Informe o nome do Aluno !!") Exit Sub End If SalvarAluno() End Sub |
O procedimento SalvarAluno() obtém a classe e o nome do aluno, define a ação e chama o método SalvaAluno() passando o objeto Aluno para persistência dos dados:
Sub SalvarAluno() Dim alnBLL As New AlunosBLL Dim aln As New Aluno Dim cls As New Classe Dim clsBLL As New ClasseBLL Try 'obtem a classe selecionada cls = clsBLL.GetClassePorCodigo(cboClasses.SelectedIndex + 1) 'obtem o id da classe aln.ClasseId = cls.ClasseId 'obtem o nome do aluno aln.NomeAluno = Me.txtNovoAluno.Text 'define a ação aln.Acao = FlagAcao.Insert 'usa o método para salvar o aluno alnBLL.SalvaAluno(aln) MessageBox.Show("Dados do aluno atualizado com sucesso !!") Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub |
Estamos sobrescrevendo o método Refresh do formulário onde atualizamos o controle combobox cboClasses conforme abaixo:
Public Overloads Sub Refresh(ByVal intID As Integer) cboClasses.DataSource = _classes cboClasses.Refresh() cboClasses.SelectedIndex = intID End Sub |
Finalmente o evento CLick do botão Sair encerra a aplicação:
Private Sub btnSair_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSair.Click Application.Exit() End Sub |
Como podemos observar nossa camada de apresentação não utiliza nem usa nenhuma referência para realizar a persistência, ao invés disso ela usa os métodos da camada de negócios para realizar tais operações. Assim qualquer mudança na camada de acesso a dados não afeta diretamente nossa camada de apresentação.
O exemplo da camada de apresentação não esta completo e foi usado apenas para ilustrar a separação das responsabilidades em camadas.
Assim completamos a nossa caminhada em 7 passos onde percorremos as etapas básicas onde em cada passo abordamos os conceitos relacionados com a separação de responsabilidades e a criação de camadas.
Pegue o projeto completo aqui: AppTresCamadas.zip
Agora para concluir vou fazer uma pergunta:
Você acha que nossa aplicação pode ser considerada uma aplicação orientada a objetos ?
Não.
Ela usa uma abordagem procedural que mescla a utilização dos recursos da orientação a objetos disponíveis na linguagem VB .NET.
Em uma aplicação totalmente orientada a objetos a abordagem seria diferente...
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
("É lamentável que muito do que hoje é chamado de 'programação orientada a objetos' é simplemente o velho estilo de programação com uma construção mais extravagante." by google)
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: