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:
  • GetTodasClasses
  • GetClassePorCodigo
  • Salvar
  • DeletarClasse

Esta classe esta apenas usando os métodos criados para
acessar os métodos correspondentes na camada CamadaDAL

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:
  • GetTodosAlunos
  • GetAlunosPorCodigo
  • GetAlunosPorClasse
  • SalvaAluno
  • DeletaAluno

Esta classe esta apenas usando os métodos criados para
acessar os métodos correspondentes na camada CamadaDAL

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

  • CboClasses
  • txtNovaClasse
  • btnNovaClasse
  • btnSalvarClasse

GroupBox - grpAlunos - Text = Alunos

  • dgvAlunos
  • txtNovoAluno
  • bntSair
  • btnSalvarAluno

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:


José Carlos Macoratti