Visual Basic 2008 9.0 .NET Examples and Ebook
  Home

Object Oriented Programming

Vorig Onderwerp

Procedures and Functions

|

New in Visual Basic 2008 - 9.0

Volgend Onderwerp

Implementation

Vorig Onderwerp

Properties

|

Containment

Volgend Onderwerp
Caching versus Calculation

Caching versus Calculation

Unit Tests

Unit Tests

Exercises

Exercises



Caching versus Calculation


An alternative to calculation the value of a derived attribute in the getfunction GetPriceIncludingTax is to calculate that value in the setters of the base-state properties ( Price en Tax ).
That value can then be cached away ( in m_PriceIncludingTax ), and then simple be collected when asked for ( in the getfunction GetPriceIncludingTax.


Namespace Example1
    Class Product
        Private m_Price As Decimal
        Public Property Price() As Decimal
            Get
                Price = m_Price
            End Get
            Set(ByVal value As Decimal)
                m_Price = value
                setPriceIncludingTax()
            End Set
        End Property
        Private m_TaxPercentage As Decimal
        Public Property TaxPercentage() As Decimal
            Get
                TaxPercentage = m_TaxPercentage
            End Get
            Set(ByVal value As Decimal)
                m_TaxPercentage = value
                setPriceIncludingTax()
            End Set
        End Property
        Private m_PriceIncludingTax As Decimal
        Public Function GetPriceIncludingTax() As Decimal
            GetPriceIncludingTax = m_PriceIncludingTax
        End Function
        Private Sub setPriceIncludingTax()
            m_PriceIncludingTax = Price * (1 + (TaxPercentage / 100))
        End Sub
    End Class
    Module Client
        Sub Main()
            Dim product1 As Product = New Product
            product1.Price = 100
            product1.TaxPercentage = 8
            Console.WriteLine(product1.GetPriceIncludingTax())
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 108

This can be an advantage when querying/getting GetPriceIncludingTax happens more often then setting Price or Tax. Less calculations have to be made.

But watch out, there to avoid making to many assumptions about the way objects of your classes will be used, like the order an frequency the members will be called.
Always try to design classes that can be used efficiently in all kinds of situations,

An obvious disadvantage of the method ( caching the derived values ) is that the logic about how and when the derived values have to be calculated is spread over different members of the class, and consequently will be more complex to maintain or scale. Often lots of synchronization code needs to be added.

Chose wisely whether or not to cache a derived state, and be aware of the consequences of your decision.

Some coding guidelines suggest using a 'Property' when you're accessing a field directly, in this case a 'ReadOnly Property'. Following these guidelines we change the class to :


Namespace Example2
    Class Product
        Private m_Price As Decimal
        Public Property Price() As Decimal
            Get
                Price = m_Price
            End Get
            Set(ByVal value As Decimal)
                m_Price = value
                setPriceIncludingTax()
            End Set
        End Property
        Private m_TaxPercentage As Decimal
        Public Property TaxPercentage() As Decimal
            Get
                TaxPercentage = m_TaxPercentage
            End Get
            Set(ByVal value As Decimal)
                m_TaxPercentage = value
                setPriceIncludingTax()
            End Set
        End Property
        Private m_PriceIncludingTax As Decimal
        Public ReadOnly Property PriceIncludingTax() As Decimal
            Get
                PriceIncludingTax = m_PriceIncludingTax
            End Get
        End Property
        Private Sub setPriceIncludingTax()
            m_PriceIncludingTax = Price * (1 + (TaxPercentage / 100))
        End Sub
    End Class
    Module Client
        Sub Main()
            Dim product1 As Product = New Product
            product1.Price = 100
            product1.TaxPercentage = 8
            Console.WriteLine(product1.PriceIncludingTax)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 108

Klik hier om terug naar boven te gaan.  Up


Unit Tests


For each of the following classes a "test fixture" is created.

The members of each class ( each "unit" ) is tested for the expected behaviour.

These fixtures make an instance of the class that has to be tested, and will test the command ( procedures ) using the queries ( functions ).

These tests define the behaviour we expect from the classes.

It's useful to define the tests before defining the classes ( "testdriven development" ). By doing this you reflect on the abstraction, the public interface and the expected behaviour of these classes.
Once the tests are defined, you can easily start implementing your classes until all tests run successfully.


Klik hier om terug naar boven te gaan.  Up


Exercises


Task 1 :

Make it possible to create objects that represent an addition. An addition has two values ( each settable and queryable ) and a result ( queryable ).


Solution 1 :


Namespace Exercise1
    Class Addition
        Private m_Value1 As Integer
        Public Property Value1() As Integer
            Get
                Value1 = m_Value1
            End Get
            Set(ByVal value As Integer)
                m_Value1 = value
            End Set
        End Property
        Private m_Value2 As Integer
        Public Property Value2() As Integer
            Get
                Value2 = m_Value2
            End Get
            Set(ByVal value As Integer)
                m_Value2 = value
            End Set
        End Property
        Public Function GetResult() As Integer
            GetResult = Value1 + Value2
        End Function
    End Class
    Module AdditionTestFixture
        Sub Main()
            Dim addition1 As Addition = New Addition
            Console.WriteLine(addition1.Value1 = 0)
            Console.WriteLine(addition1.Value2 = 0)
            Console.WriteLine(addition1.GetResult() = 0)
            '
            addition1.Value1 = 1                                           ' (1)
            Console.WriteLine(addition1.Value1 = 1)
            Console.WriteLine(addition1.Value2 = 0)                        ' (2)
            Console.WriteLine(addition1.GetResult() = 1)
            '
            addition1.Value2 = 2
            Console.WriteLine(addition1.Value1 = 1)
            Console.WriteLine(addition1.Value2 = 2)
            Console.WriteLine(addition1.GetResult() = 3)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 True
 True
 True
 True
 True
 True
 True
 True
 True

It may seem unnecessary to test if property 'Value2' is 0 (2) after setting property 'Value1' (1). Still it is useful to test if setting 'Value1' doesn't ( "accidentally" ) alter 'Value2'.


Task 2 :


Make it possible to create lamp objects. A simple press button on each lamp can be used to make the lamp give light, or to stop the lamp from giving light.


Solution 2 :


Namespace Exercise2
    Class Lamp
        Private m_GivesLight As Boolean
        Public ReadOnly Property GivesLight() As Boolean
            Get
                GivesLight = m_GivesLight
            End Get
        End Property
        Public Sub PressButton()
            m_GivesLight = Not m_GivesLight
        End Sub
    End Class
    Module LampTestFixture
        Sub Main()
            Dim lamp1 As Lamp = New Lamp
            Console.WriteLine(lamp1.GivesLight = False)
            '
            lamp1.PressButton()
            Console.WriteLine(lamp1.GivesLight = True)
            '
            lamp1.PressButton()
            Console.WriteLine(lamp1.GivesLight = False)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 True
 True
 True

Task 3 :


Make it possible to create counter objects. Each counter has a queryable value and a stepvalue ( settable and queryable ). To manipulate the value of a counter you must be able to give the counter the commands to raise ( value incremented with 1 ) or to lower ( value decremented with 1 ) itself.
The value is initially 0, the stepvalue 1.


Solution 3 :


Namespace Exercise3
    Class Counter
        Private m_Value As Integer
        Public Property Value() As Integer
            Get
                Value = m_Value
            End Get
            Set(ByVal value As Integer)
                m_Value = value
            End Set
        End Property
        Private m_StepValue As Integer = 1
        Public Property StepValue() As Integer
            Get
                StepValue = m_StepValue
            End Get
            Set(ByVal value As Integer)
                m_StepValue = value
            End Set
        End Property
        Public Sub Raise()
            Value += StepValue
        End Sub
        Public Sub Lower()
            Value -= StepValue
        End Sub
    End Class
    Module CounterTestFixture
        Sub Main()
            Dim counter1 As Counter = New Counter
            Console.WriteLine(counter1.Value = 0)
            Console.WriteLine(counter1.StepValue = 1)
            '
            counter1.Value = 10
            Console.WriteLine(counter1.Value = 10)
            Console.WriteLine(counter1.StepValue = 1)
            '
            counter1.StepValue = 5
            Console.WriteLine(counter1.Value = 10)
            Console.WriteLine(counter1.StepValue = 5)
            '
            counter1.Raise()
            Console.WriteLine(counter1.Value = 15)
            Console.WriteLine(counter1.StepValue = 5)
            '
            counter1.Lower()
            Console.WriteLine(counter1.Value = 10)
            Console.WriteLine(counter1.StepValue = 5)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 True
 True
 True
 True
 True
 True
 True
 True
 True
 True

Task 4 :


Make a class that simulates a simple robot. The robot can move over a coordinate system ( X and Y coordinates ) in horizontal or vertical direction.

A robot can only given the command to rotate ( always 90 degrees clockwise ) and to place a step ( which shifts the robot 1 unit over then X- or Y-axis ).

Make a robot queryable for it X and Y position.

Initially the robot is in oriented in north direction and is on X position 0 and Y position 0.


Solution 4 :


Namespace Exercise4
    Class Robot
        Private m_X As Integer
        Public ReadOnly Property X() As Integer
            Get
                X = m_X
            End Get
        End Property
        Private m_Y As Integer
        Public ReadOnly Property Y() As Integer
            Get
                Y = m_Y
            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
                    m_Y += 1
                Case 1 ' right
                    m_X += 1
                Case 2 ' down
                    m_Y -= 1
                Case 3 ' left
                    m_X -= 1
            End Select
        End Sub
    End Class
    Module RobotTestFixture
        Public Sub Main()
            Dim robot1 As Robot = New Robot
            Console.WriteLine(robot1.X = 0)
            Console.WriteLine(robot1.Y = 0)
            '
            robot1.PlaceStep()
            Console.WriteLine(robot1.X = 0)
            Console.WriteLine(robot1.Y = 1)
            '
            robot1.PlaceStep()
            Console.WriteLine(robot1.X = 0)
            Console.WriteLine(robot1.Y = 2)
            '
            robot1.Rotate()
            Console.WriteLine(robot1.X = 0)
            Console.WriteLine(robot1.Y = 2)
            '
            robot1.PlaceStep()
            Console.WriteLine(robot1.X = 1)
            Console.WriteLine(robot1.Y = 2)
            '
            robot1.Rotate()
            robot1.PlaceStep()
            Console.WriteLine(robot1.X = 1)
            Console.WriteLine(robot1.Y = 1)
            '
            robot1.Rotate()
            robot1.PlaceStep()
            Console.WriteLine(robot1.X = 0)
            Console.WriteLine(robot1.Y = 1)
            '
            robot1.Rotate()
            robot1.PlaceStep()
            Console.WriteLine(robot1.X = 0)
            Console.WriteLine(robot1.Y = 2)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True

Updated On : 2008-05-29

Download Broncode

Published On : 2008-11-06

Implementation

Vorig Onderwerp

Properties

|

Containment

Volgend Onderwerp

Object Oriented Programming

Vorig Onderwerp

Procedures and Functions

|

New in Visual Basic 2008 - 9.0

Volgend Onderwerp
  Home  
Nederlands
Nederlands

Add to favorites (IE).


No printable version available.