| hoofdstuk |
8. 9. 10.  |
| onderwerp |
9.6. 9.7. Containment 9.8.  |
| rubrieken | 



|
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
9.7.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 2010 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 PropertyEnd ClassClass 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 PropertyEnd ClassModule 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 SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application 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 2010 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 SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application 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). boven
9.7.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 2010 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 PropertyEnd ClassDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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 2010 Broncode Module Client3 Sub Main() Dim customer1 As Customer = New Customer customer1.Address.City = "New York" Console.WriteLine(customer1.Address.City) Console.ReadLine() End SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output New York boven
9.7.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, ... . boven
9.7.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 2010 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 PropertyEnd ClassModule 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 SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output True
True
True
True
True
True Visual Basic 2010 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 SubEnd ClassModule 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 SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application 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 2010 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 SubEnd ModuleClass 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 PropertyEnd ClassClass 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 PropertyEnd ClassDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
| hoofdstuk |
8. 9. 10.  |
| onderwerp |
9.6. 9.7. Containment 9.8.  |
| broncode |
Download Containment.vb of Containment.cs |
| datum |
laatst gewijzigd op woensdag 8 april 2009, laatst gepubliceerd op zondag 31 juli 2011 |
|