VB. NET - Implementando o relacionamento um-para-muitos


Você já ouviu a frase: "Para quem sabe fazer é fácil...".

Imagine um cenário onde você esta iniciando no paradigma da orientação a objetos e tenha que definir as classes com uma associação um-para-muitos e também a sua implementação.

Você deverá definir as classes, os atributos, representar o relacionamento, gerar uma associação entre as classes e criar um projeto para mostrar a implementação das classes. Um típico exercício acadêmico que se repete aos milhares no dia a dia de um desenvolvedor que usa uma linguagem orientada a objetos.

Este é um assunto recorrente e já muito bem conhecido para quem tem uma boa experiência com programação orientada a objetos, mas o que pode parecer simples para quem têm experiência, para quem esta começando agora, pode ser um pesadelo.

Neste artigo eu vou mostrar como  definir e implementar as classes envolvidas em uma associação um-para-muitos, o mesmo existente entre duas tabelas de um banco de dados relacional. Vou mostrar também como gerar a associação entre as classes e criar um projeto para implementar a solução, enfim mostrar uma das possíveis maneiras de resolver este problema usando apenas como ferramenta o Visual Basic 2008 Express Edition que é uma linguagem orientada a objetos.

O ponto de partida:

Nosso ponto de partida será um banco de dados relacional com duas tabelas onde existe um relacionamento um-para-muitos. (assim fica mais fácil entender o exemplo das classes.)

O relacionamento um-para-muitos é o mais freqüente e ocorre quando uma linha na Tabela A pode ter muitas linhas coincidentes na Tabela B, mas uma linha na Tabela B tem uma só linha coincidente na Tabela A.

Este relacionamento é representado por => 1:N

Neste tipo de relacionamento a chave primária da tabela que tem o lado 1 vai para a tabela do lado N. No lado N ela é chamada de chave estrangeira.

No banco de dados Northwind.mdf temos um exemplo desse relacionamento entre as tabelas Customers e Orders.

Cada cliente somente é cadastrado só uma vez na tabela de Customers (por isso o campo CustomerID, na tabela Customer, é uma chave primária), portanto a tabela Customer será o lado um do relacionamento.

Ao mesmo tempo cada cliente pode fazer diversos pedidos, por isso que o mesmo Código de Cliente(CustomerID) poderá aparecer várias vezes na tabela Orders: tantas vezes quantos forem os pedidos que o Cliente tiver feito.

Por isso temos um relacionamento do tipo Um-para-Muitos entre a tabela Customers e Orders, através do campo CustomerID, indicando que um mesmo Cliente pode realizar Muitos (vários) pedidos.


Chave Primária é o campo no qual não podem haver valores repetidos

O exemplo que eu vou implementar neste artigo vai ser mais simples para tornar bem claro o entendimento a todos os que estão iniciando com a programação orientada a objetos. 

Irei definir um classe Cliente e uma classe Dependente onde um cliente pode ter nenhum ou muitos dependentes.(Para tornar o nosso exemplo mais focado na implementação das classes eu vou trabalhar com um modelo bem 'enxuto'.)

Vou implementar as classes e os métodos sem a ajuda de nenhuma ferramenta, usando apenas o Visual Basic 2008 Express Edition. Lembrando que a solução apresentada apenas é uma das soluções possíveis e não a única solução.

Abaixo temos a classe Cliente e a classe Dependente, ambas anêmicas, que podemos usar para implementar a nossa solução:

A classe Cliente possui as propriedades nome e dependentes e os métodos adicionarDependente e removerDependente;
A classe Dependente possui as propriedades Nome e Cliente;

Abaixo temos a associação entre as duas classes representação o relacionamento Um-Para-Muitos:

Como podemos observar para representar o relacionamento um-para-muitos, na classe Dependente, a classe de multiplicidade muitos, devemos adicionar um atributo do tipo da classe Cliente (_cliente), a classe de multiplicidade um, e os correspondentes métodos gets/sets para os atributos. (Aqui para facilitar o entendimento eu implementei métodos com get/set.)

Na classe Cliente, a classe de multiplicidade um, devemos ter um atributo do tipo dependentes , que represente uma coleção de itens de Dependente.(List(Of Dependente))

Dessa forma estamos representando a associação entre as classes Cliente e Dependente.

O métodos  adicionarDependente e removerDependente na classe Cliente serão usados apenas para criarmos clientes e dependentes na nossa implementação que será feita em uma aplicação Windows Forms.

Feito isso , agora é só alegria...

Vamos criar uma aplicação Windows Forms (poderia ser qualquer outro tipo de aplicação) apenas para mostrarmos como implementamos a criação das classes Cliente e Dependente, o relacionamento um-para-muitos  e selecionamos  um  cliente e seus dependentes relacionados.

Abra o Visual Basic 2008 Express Editon e crie um novo projeto do tipo Windows Application com o nome UmParaMuitos;

No formulário padrão vamos definir uma interface bem simples usando os seguintes controles:

Conforme o leiaute abaixo:

A seguir no menu Project selecione Add Class e informe informe o nome Cliente.vb para o arquivo da classe que conterá a definição da classe Cliente.

A seguir defina o código da classe Cliente conforme abaixo:

Public Class Cliente
    Private nome As String
    Private dependentes As List(Of Dependente)
    Public Sub New()
        Me.dependentes = New List(Of Dependente)()
    End Sub

    Public Sub New(ByVal nome As String)
        Me.nome = nome
        Me.dependentes = New List(Of Dependente)()
    End Sub

    Public Sub setNome(ByVal nome As String)
        Me.nome = nome
    End Sub

    Public Function getNome() As String
        Return (Me.nome)
    End Function
    Public Function getDependentes() As List(Of Dependente)
        Return (dependentes)
    End Function
    Public Sub setDependentes(ByVal dependentes As List(Of Dependente))
        For Each d As Dependente In dependentes
            Me.adicionarDependente(d)
        Next
    End Sub

    Public Sub adicionarDependente(ByVal dependente As Dependente)
        Me.dependentes.Add(dependente)
    End Sub

    Public Sub removerDependente(ByVal dependente As Dependente)
        Me.dependentes.Remove(dependente)
    End Sub

End Class

A classe é bem simples e é composta de:

Repita o procedimento para criar a classe Dependente e a seguir defina o nome do arquivo como Dependente.vb.

Em seguida  inclua o código abaixo para definir a classe Dependente:

Public Class Dependente
    Private _nome As String
    Private _cliente As Cliente

    Public Sub New(ByVal _nome As String)
        Me.getNome(_nome)
    End Sub

    Public Sub New(ByVal nome As String, ByVal cliente As Cliente)
        Me.getNome(nome)
        Me.setCliente(cliente)
    End Sub

    Public Sub setNome(ByVal nome As String)
        Me._nome = nome
    End Sub

    Public Function getNome() As String
        Return _nome
    End Function

    Public Function getCliente() As Cliente
        Return (Me._cliente)
    End Function

    Public Sub setCliente(ByVal cliente As Cliente)
        If Me._cliente IsNot Nothing Then
            Me._cliente.removerDependente(Me)
        End If
        Me._cliente = cliente
        If Me._cliente IsNot Nothing Then
            Me._cliente.adicionarDependente(Me)
        End If
    End Sub
End Class

A classe Dependente é composta de:

Agora vamos usar o evento Click do botão Carregar para implementarmos criarmos instâncias da classes,  criar e definir clientes e dependentes e exibir o seu relacionamento.

Inclua o código abaixo neste evento:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Vamos criar uma instância do objeto clienteUm definindo o seu nome como Macoratti
        Dim clienteUm As New Cliente("Macoratti")
        'A seguir vamos criar uma instância para dependente1 atribuindo o nome Jefferson
        'e definindo que ele pertence ao cliente Macoratti(clienteUm)
        Dim dependente01 As New Dependente("jefferson", clienteUm)
        'A seguir vamos criar uma instância para dependente2 atribuindo o nome Jessica
        'e definindo que ele pertence ao cliente Macoratti(clienteUm)
        Dim dependente02 As New Dependente("jessica")
        dependente02.setCliente(clienteUm)
        'vamos listar o nome do cliente para o objeto clienteUm
        ListBox1.Items.Add("Dependentes do cliente => " & clienteUm.getNome())
        'a seguir vamos exibir a relação dos dependentes para clienteUm
        Dim dependentes As List(Of Dependente) = clienteUm.getDependentes()
        For Each d As Dependente In dependentes
            ListBox1.Items.Add(d.getNome())
        Next
        'Agora vamos exibir o nome do dependente02 = Jessica
        ListBox1.Items.Add("Cliente do dependente : " & dependente02.getNome())
        ' criamos um objeto clienteDependente02 do tipo Cliente e obtemos o seu nome
        Dim clienteDependente02 As Cliente = dependente02.getCliente()
        'exibimos o nome do cliente referente ao dependente Jessica
        ListBox1.Items.Add(clienteDependente02.getNome())
        'A seguir criamos um objeto depen que representa uma lista de depententes
        Dim depen As New List(Of Dependente)()
        'definimos e incluimos na lista 3 dependentes: Bianca, Yuri e Janice
        depen.Add(New Dependente("Bianca"))
        depen.Add(New Dependente("Yuri"))
        depen.Add(New Dependente("Janice"))
        'criamos uma instância do objeto clienteDois definindo o seu nome como Carlinhos
        Dim clienteDois As New Cliente("Carlinhos")
        'atribuimos ao cliente a lista de dependentes criada
        clienteDois.setDependentes(depen)
        'listamos o nome do cliente - clienteDois
        ListBox1.Items.Add("Dependentes do cliente => " & clienteDois.getNome())
        'exibimos a relação de dependentes para o clienteDois
        Dim depende As List(Of Dependente) = clienteDois.getDependentes()
        For Each d As Dependente In depende
            ListBox1.Items.Add(d.getNome())
        Next
    End Sub

Executando o projeto iremos obter:

Com isso abordamos conceitos básicos e essenciais da orientação a objeto em como implementar um relacionamento um-para-muitos. Repito, esta é uma das muitas implementações possíveis.

Pegue o projeto completo aqui: ORM_UmMuitos.zip

Eu sei é apenas VB .NET, mas eu gosto ...

Referências:


José Carlos Macoratti