homeboekenlinksledenabonneer je :Blijf op de hoogte door je te abonneren op de vbvoorbeelden RSS Niews Feed!Blijf op de hoogte door vbvoorbeelden te volgen op Twitter!Blijf op de hoogte door fan te worden van vbvoorbeelden op Facebook!
Visual Basic 2008 en 2010 Voorbeelden en Boeken Microsoft Visual Studio 2010Microsoft Developers Network - Visual BasicMicrosoft .NET Framework

visual basic 2008 voorbeelden en boeken / visual basic 2010 voorbeelden en boeken

9.5. Containment

Print Email Deel op FacebookDeel op TwitterDeel op DiggBookmark op Google BookmarksDeel op del.icio.usOverige Sociale Netwerksites...

Dit artikel is gepubliceerd op woensdag 28 april 2010 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

9.5.1. Een Verband tussen Objecten

Vaak komt het voor dat objecten van ( verschillende ) types een verband met elkaar hebben. Dat beide types dus geassocieerd zijn.
Dergelijke associatie kan ontstaan wanneer één object een ( ander ) object heeft. Van hier spreek ik in dat geval over een containment-relatie, die doorgaans gekenmerkt wordt door de "heeft-een" relatie tussen de entiteiten.

Bijvoorbeeld : een Person heeft een Address.
Visual Basic Broncode
Class Person
    Private m_Name As String
    Public Property Name() As String
        Get
            Name = m_Name
        End Get
        Set(ByVal value As String)
            m_Name = value
        End Set
    End Property
    Private m_Address As Address
    Public Property Address() As Address
        Get
            Address = m_Address
        End Get
        Set(ByVal value As Address)
            m_Address = value
        End Set
    End Property
End Class
Class Address
    Private m_Street As String
    Public Property Street() As String
        Get
            Street = m_Street
        End Get
        Set(ByVal value As String)
            m_Street = value
        End Set
    End Property
    Private m_Number As String
    Public Property Number() As String
        Get
            Number = m_Number
        End Get
        Set(ByVal value As String)
            m_Number = value
        End Set
    End Property
    Private m_ZipCode As String
    Public Property ZipCode() As String
        Get
            ZipCode = m_ZipCode
        End Get
        Set(ByVal value As String)
            m_ZipCode = value
        End Set
    End Property
    Private m_City As String
    Public Property City() As String
        Get
            City = m_City
        End Get
        Set(ByVal value As String)
            m_City = value
        End Set
    End Property
End Class
Module Client1
    Sub Main()
        Dim address1 As Address = New Address
        address1.Street = "Royal Avenue"
        address1.Number = "10"
        address1.ZipCode = "90210"
        address1.City = "Beverly Hills"
        '
        Dim person1 As Person = New Person
        person1.Name = "John"
        person1.Address = address1
        '
        Print(person1)
        '
        Console.ReadLine()
    End Sub
    Sub Print(ByVal person As Person)
        Console.WriteLine(person.Name)
        If person.Address IsNot Nothing Then
            With person.Address
                Console.WriteLine(.Number & ", " & .Street)
                Console.WriteLine(.City & " " & .ZipCode)
            End With
        End If
    End Sub
End Module
Visual Basic Output
John
10, Royal Avenue
Beverly Hills 90210
Het With [object-expression] ... End With blok is bruikbaar om tussen With en End With op verkorte wijze ( men kan de objectexpressie zelf weglaten ) te verwijzen naar de members van het object waarnaartoe deze objectexpressie verwijst.

Een object van de klasse Person kan hier beschikken over een referentie van een Address object. Op deze wijze kan een associatie tussen deze 2 entiteiten worden bijgehouden.

In bovenstaande Main procedure wordt eerst een variabele ( address1 ) opgevuld met de referentie van een nieuw Address object, om deze vervolgens te gebruiken als setvalue voor de eigenschap Address van Person.

Op zich zou men het gebruik van deze variabele ( address1 ) kunnen vermijden.
Visual Basic Broncode
Module Client2
    Sub Main()
        Dim person1 As Person = New Person
        person1.Name = "John"
        person1.Address = New Address
        person1.Address.Street = "Royal Avenue"                            ' (1)
        person1.Address.Number = "10"
        person1.Address.ZipCode = "90210"
        person1.Address.City = "Beverly Hills"
        Print(person1)
        '
        Dim person2 As Person = New Person
        person2.Name = "Jane"
        person2.Address = person1.Address                                  ' (2)
        Print(person2)
        '
        Console.ReadLine()
    End Sub
End Module
Visual Basic Output
John
10, Royal Avenue
Beverly Hills 90210
Bemerk de doorgedreven puntnotatie dat gebruikt kan worden om bijvoorbeeld te verwijzen naar de eigenschap Street van het Address van een Person (1).

9.5.2. Herbruik van Klassen en Code

Bemerk ook hoe eenvoudig het is om verschillende personen gebruik te laten maken van hetzelfde adres ( hetzelfde Address object ) (2).
Dit kan natuurlijk enkel doordat Address een aparte constructie is. Hadden we de eigenschappen Street, Number, ZipCode en City in de constructie Person opgenomen, dan hadden we voor deze personen ( person1 en person2 ) de adresgegevens moeten dupliceren.

In bovenstaand voorbeeld werd ervoor ge-opteerd de client een object van het type Address te laten instantiëren, en vervolgens toe te kennen aan de eigenschap Address van het Person object.

Het alternatief is objecten van het Person type zelf een object van het type Address te laten instantiëren, zoals in onderstaand voorbeeld gebeurt in de Customer klasse (1).
Visual Basic Broncode
Class Customer
    Private m_Name As String
    Public Property Name() As String
        Get
            Name = m_Name
        End Get
        Set(ByVal value As String)
            m_Name = value
        End Set
    End Property
    Private m_Address As Address = New Address                             ' (1)
    Public Property Address() As Address
        Get
            Address = m_Address
        End Get
        Set(ByVal value As Address)
            m_Address = value
        End Set
    End Property
End Class
Het verschil zit hem hier in regel (1) waar het veld m_Address meteen geïnitialiseerd wordt met een verwijzing naar een nieuw geïnstantieerd object van het type Address.

Hierbij is het niet meer nodig de client zelf een object te laten maken van deze Address klasse.
Visual Basic Broncode
Module Client3
    Sub Main()
        Dim customer1 As Customer = New Customer
        customer1.Address.City = "New York"
        '
        Console.WriteLine(customer1.Address.City)
        '
        Console.ReadLine()
    End Sub
End Module
Visual Basic Output
New York

9.5.3. Wie is Verantwoordelijk voor het Creëren van een Object

Of men al dan niet het contained object laat creëren door het containing object is afhankelijk van een aantal factoren.

Indien het containing object de enigste is die moet beschikken over het contained object, of indien het containing object beschikt over de kennis welke de initialisatiedata is voor het contained object, dan zal men waarschijnlijk het containing object verantwoordelijk maken voor het creëren van het contained object ( "GRASPattern Creator" ).

In dit geval zou je kunnen stellen dat een adres door meerdere personen of klanten kan gedeeld worden. Het lijkt dan ook het meest voor de hand liggend om de client verantwoordelijk te maken voor het expliciet instantiëren van een Address object.

Je ziet ook hoe het mogelijk is in meerdere klassen ( als Person en Customer ) dezelfde klasse ( als Address ) te herbruiken. Containment kan dus leiden tot het herbruik van code.

Andere voorbeelden van containment kunnen zijn : een computer heeft een processor, een factuur heeft een klant ( of anders gesteld een factuur is van toepassing op een klant ), een wagen heeft een motor, een boek heeft een index, ... .

9.5.4. Oefeningen

Opgave 1 :

Pas de klasse Robot uit vorig onderwerp aan. Laat een Robot gebruik maken van een Position, die een positie op een XY-assenstelsel voorstelt.
Oplossing 1 :
Visual Basic Broncode
Class Position
    Private m_X As Integer
    Public Property X() As Integer
        Get
            X = m_X
        End Get
        Set(ByVal value As Integer)
            m_X = value
        End Set
    End Property
    Private m_Y As Integer
    Public Property Y() As Integer
        Get
            Y = m_Y
        End Get
        Set(ByVal value As Integer)
            m_Y = value
        End Set
    End Property
End Class
Module PositionTextFixture
    Sub Main()
        Dim position1 As Position = New Position
        Console.WriteLine(position1.X = 0)
        Console.WriteLine(position1.Y = 0)
        '
        position1.X = 5
        Console.WriteLine(position1.X = 5)
        Console.WriteLine(position1.Y = 0)
        '
        position1.Y = 10
        Console.WriteLine(position1.X = 5)
        Console.WriteLine(position1.Y = 10)
        '
        Console.ReadLine()
    End Sub
End Module
Visual Basic Output
True
True
True
True
True
True
Visual Basic Broncode
Class Robot
    Private m_Position As Position = New Position
    Public ReadOnly Property Position() As Position
        Get
            Position = m_Position
        End Get
    End Property
    Private m_Direction As Integer
    Public Sub Rotate()
        m_Direction += 1
        If m_Direction > 3 Then m_Direction = 0
    End Sub
    Public Sub PlaceStep()
        Select Case m_Direction
            Case 0 ' up
                Position.Y = Position.Y + 1
            Case 1 ' right
                Position.X = Position.X + 1
            Case 2 ' down
                Position.Y = Position.Y - 1
            Case 3 ' left
                Position.X = Position.X - 1
        End Select
    End Sub
End Class
Module RobotTestFixture
    Public Sub Main()
        Dim robot1 As Robot = New Robot
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 0)
        '
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 1)
        '
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        robot1.Rotate()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 1)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        robot1.Rotate()
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 1)
        Console.WriteLine(robot1.Position.Y = 1)
        '
        robot1.Rotate()
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 1)
        '
        robot1.Rotate()
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        Console.ReadLine()
    End Sub
End Module
Visual Basic Output
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
Hier werd ervoor ge-opteerd om een Robot zelf een Position object te laten creëren. Dit omdat elk Robot object intensief gebruik maakt van zijn containde Position object.

De eigenschap Position in Robot is readonly gemaakt, het is immers mogelijk om via de commands Rotate en PlaceStep de toestand van het containde Position object te gaan manipuleren.
Opgave 2 :
Creëer een klasse waarvan objecten een voorstelling zijn van een punt op een XY-assenstelsel. Een punt heeft als eigenschappen een X en Y positie.

Creëer ook een klasse waarvan objecten een voorstelling zijn van een lijn, met een start- en eindpunt. Van de lijn moet je de lengte kunnen opvragen.
Oplossing 2 :
Visual Basic Broncode
Module PointAndLineTestFixtures
    Sub Main()
        PointTestFixture()
        LineTextFixture()
        '
        Console.ReadLine()
    End Sub
    Sub PointTestFixture()
        Dim point1 As Point = New Point
        Console.WriteLine(point1.X = 0)
        Console.WriteLine(point1.Y = 0)
        '
        point1.X = 1
        Console.WriteLine(point1.X = 1)
        Console.WriteLine(point1.Y = 0)
        '
        point1.Y = 3
        Console.WriteLine(point1.X = 1)
        Console.WriteLine(point1.Y = 3)
    End Sub
    Sub LineTextFixture()
        Dim line1 As Line = New Line
        Console.WriteLine(line1.StartPoint Is Nothing)
        Console.WriteLine(line1.EndPoint Is Nothing)
        Console.WriteLine(line1.Length = 0)
        '
        Dim startPoint As Point = New Point With {.X = 1, .Y = 4}
        line1.StartPoint = startPoint
        Console.WriteLine(line1.StartPoint Is startPoint)
        Console.WriteLine(line1.EndPoint Is Nothing)
        Console.WriteLine(line1.Length = 0)
        '
        Dim endPoint As Point = New Point With {.X = 5, .Y = 1}
        line1.EndPoint = endPoint
        Console.WriteLine(line1.StartPoint Is startPoint)
        Console.WriteLine(line1.EndPoint Is endPoint)
        Console.WriteLine(line1.Length = 5)
    End Sub
End Module
Class Point
    Private m_X As Integer
    Public Property X() As Integer
        Get
            X = m_X
        End Get
        Set(ByVal value As Integer)
            m_X = value
        End Set
    End Property
    Private m_Y As Integer
    Public Property Y() As Integer
        Get
            Y = m_Y
        End Get
        Set(ByVal value As Integer)
            m_Y = value
        End Set
    End Property
End Class
Class Line
    Private m_StartPoint As Point
    Public Property StartPoint() As Point
        Get
            StartPoint = m_StartPoint
        End Get
        Set(ByVal value As Point)
            m_StartPoint = value
        End Set
    End Property
    Private m_EndPoint As Point
    Public Property EndPoint() As Point
        Get
            EndPoint = m_EndPoint
        End Get
        Set(ByVal value As Point)
            m_EndPoint = value
        End Set
    End Property
    Public ReadOnly Property Length() As Double
        Get
            If StartPoint IsNot Nothing AndAlso EndPoint IsNot Nothing Then
                Dim side1 As Integer = Math.Abs(StartPoint.X - EndPoint.X)
                Dim side2 As Integer = Math.Abs(StartPoint.Y - EndPoint.Y)
                Length = Math.Sqrt(Math.Pow(side1, 2) + Math.Pow(side2, 2))
            End If
        End Get
    End Property
End Class
Visual Basic Output
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True

Dit artikel is gepubliceerd op woensdag 28 april 2010 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

Visual Basic 2008 & 2010 Boeken

Het Groene Visual Basic 2008 & 2010 Voorbeelden Boek Het Blauwe Visual Basic 2008 & 2010 Voorbeelden Boek Het Rode Visual Basic 2008 & 2010 Voorbeelden Boek

Bevalt een artikel je, dan kan je de inhoud van vbvoorbeelden ook reclamevrij in boekvorm verkrijgen.

De inhoud is verdeeld over 3 boeken, Het Groene, Het Blauwe en Het Rode Visual Basic 2008 & 2010 Voorbeelden Boek.

Klik hier voor meer informatie.

Berichten

Fast UML Sequence Diagram Editor