|
|
 |
|
|
|
|
Visual Basic 2008 9.0 .NET Examples and Ebook
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
An Association between Objects
| Often objects of (a) (different) type(s) have an association between them. One type of association is a "has as" relation between objects of this (different) type(s). From here on I'll refer to this type of association as "containment".
For instance : a Person has an Address. |
| Class Person
Private m_Name As String
Public Property Name() As String
Get
Return 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 Download Broncode |
| Output : John
10, Royal Avenue
Beverly Hills 90210 |
| The With [object-expression] ... End With-block is useful to address the members of the object ( of the objectexpression ) without addressing the object itself.
An object of type Person can have a reference of an Address object. By containing this reference, the Person object can remember with which Address object it is associated.
First the variable address1 in the Main procedure is filled with a reference to some new Address object. The expression address1 is then used to express which address has to be associated with object person1. This is done by injecting the address reference in the person object thru the SetAddress command.
We can avoid the use of the variable address1 when we immediately inject the Person object with some new Address instance. |
| 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 Module Download Broncode |
| Output : John
10, Royal Avenue
Beverly Hills 90210 |
Up
Reuse of Classes and Code
| You can see how easy it is to let different Person objects ( person1 and person2 ) use the same Address object (2). This could only be made possible by isolating the address property in its own construction ( class Address ). Had we includes the properties Street, Number, ZipCode and City in Person, then all Person objects would have their own address properties.
The client of the above example first has to make the object of type Address and can only then set the address of a person.
An alternative would be to let objects of type Person create there own associated/contained Address object. This is what happens in objects of the containing type Customer that contain an object of contained type Address (1). |
| 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 Class Download Broncode |
| The field m_Address is initialized to a reference of a new Address object. Immediately when a Customer object is created, an Address object is created as well.
The client no longer has to make the contained Address object. |
| 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 Download Broncode |
Up
Who is Responsible for Creating an Object
| whether or not the containing object has to be responsible for creating the contained object depends on the situation and the needed construction.
When the containing object is the only object which has to use the contained object, or in situations where the containing object know what initialization data should be used for creation the contained object, then the containing object is made responsible for creating the contained object. ( "GRASPattern Creator" ).
When multiple objects of the containing type have to share the same object of the contained type, it useless to let all containing object first create their own contained object.
Containment allows code to be reused, both Person and Custom can use the members of Address.
Other examples of containment can be : a computer has a processor, an invoice has a customer, a book has an index, ... . |
Up
Exercise
| Task :
Adjust our class Robot, created in previous topic. Let object of type Robot use an object of type Position. A Position object has a X and a Y property. |
| 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 Download Broncode |
| Output : True
True
True
True
True
True |
| 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 Module Download Broncode |
| 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 |
| Objects of the containing type Robot create their own objects of the contained type Position. Each robot has to intensively use ( manipulate ) its own position on the grid.
The property position in Robot is made readonly ( only a GetPosition, no SetPosition ). In this abstraction only the command PlaceStep can manipulate the position. When you would want an abstraction which allows clients to set the robot to a specific position, you simple have to add something like SetPosition. |
This version ( published on 2008-06-24 ) is printed from http://www.studyvb.com, visit the website for more recent information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|