| datum |
laatst gewijzigd op woensdag 8 april 2009, laatst gepubliceerd op woensdag 28 april 2010 |
| broncode |
Download Containment.vb of Containment.cs |
| hoofdstuk |
8. 9. 10.  |
| onderwerp |
9.4. 9.5. Containment 9.6.  |
| rubrieken | 



|
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 ObjectenVaak 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 ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
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"
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
Print(person2)
Console.ReadLine()
End Sub
End ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
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). Terug naar boven 9.5.2. Herbruik van Klassen en CodeBemerk 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
Public Property Address() As Address
Get
Address = m_Address
End Get
Set(ByVal value As Address)
m_Address = value
End Set
End Property
End ClassDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
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 ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Visual Basic Output New York Terug naar boven
9.5.3. Wie is Verantwoordelijk voor het Creëren van een ObjectOf 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, ... . Terug naar boven
9.5.4. OefeningenOpgave 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 ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
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
Position.Y = Position.Y + 1
Case 1
Position.X = Position.X + 1
Case 2
Position.Y = Position.Y - 1
Case 3
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 ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
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 ClassDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
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
Berichten
|