10. Object-oriented programming revisited

By doing this, no longer is the code of the GUI mixed up with the code of the carpark. Indeed, it would now be easier to create several carparks: we would not have to duplicate the code for adding to the ArrayList or for visiting each element of the ArrayList, and so on.

The class declaration for CarPark hides an ArrayList and provides a number of methods for clients to access the ArrayList indirectly. This idea of hiding fields behind access methods is called information hiding or data encapsulation.

It may seem like a complicated way of providing an object and accessing it. However, you should view the class declaration as documenting a design decision. At the moment, we have chosen to represent a carpark by an ArrayList. At a later stage, we may feel that this is wrong: we may want to use some other representation. Since we have retained control over the access to the field of the class by making it private and providing access methods, we can make changes like this with only minimal impact to the code of the program: we know that the only code that needs to be changed is located in the methods of the CarPark class.

To demonstrate this, here is a different version of the CarPark class: in this version, the events are recorded in a MySQL database. The important thing to notice that the only code that needs to be changed is the code of the CarPark class: there are no changes to the Form1 class.

0505: Imports System.Text
0506: Imports System.Data.Odbc
0507: Public Class CarPark
0508:     Private iConnectionString As String = _
0509:             "DSN=Pdcl0bjc_CarParkVB;UID=dcl0bjc;PWD=XXXXXXX;"
0510:     Public Sub New()
0511:         Console.WriteLine("CarPark New")
0512:     End Sub
0513:     Public Sub Arrive(ByVal pString As String)
0514:         Dim tSQLString As String = _
0515:                 "INSERT INTO vehicles SET number = '" + pString + "'"
0516:         Console.WriteLine(tSQLString)
0517:         Dim tOdbcConnection As OdbcConnection = _
0518:                 New OdbcConnection(iConnectionString)
0519:         Dim tOdbcCommand As OdbcCommand = _
0520:                 New OdbcCommand(tSQLString, tOdbcConnection)
0521:         Try
0522:             tOdbcConnection.Open()
0523:             tOdbcCommand.ExecuteNonQuery()
0524:             tOdbcConnection.Close()
0525:         Catch pException As Exception
0526:             MessageBox.Show(pException.Message)
0527:         End Try
0528:     End Sub
0529:     Public Sub Depart(ByVal pString As String)
0530:         Dim tSQLString As String = _
0531:                 "DELETE FROM vehicles WHERE number = '" + pString + "'"
0532:         Console.WriteLine(tSQLString)
0533:         Dim tOdbcConnection As OdbcConnection = _
0534:                 New OdbcConnection(iConnectionString)
0535:         Dim tOdbcCommand As OdbcCommand = _
0536:                 New OdbcCommand(tSQLString, tOdbcConnection)
0537:         Try
0538:             tOdbcConnection.Open()
0539:             tOdbcCommand.ExecuteNonQuery()
0540:             tOdbcConnection.Close()
0541:         Catch pException As Exception
0542:             MessageBox.Show(pException.Message)
0543:         End Try
0544:     End Sub
0545:     Public Overrides Function ToString() As String
0546:         Dim tStringBuilder As StringBuilder = New StringBuilder
0547:         Dim tSQLString As String = "SELECT number FROM vehicles"
0548:         Console.WriteLine(tSQLString)
0549:         Dim tOdbcConnection As OdbcConnection = _
0550:                 New OdbcConnection(iConnectionString)
0551:         Dim tOdbcCommand As OdbcCommand = _
0552:                 New OdbcCommand(tSQLString, tOdbcConnection)
0553:         Try
0554:             tOdbcConnection.Open()
0555:             Dim tOdbcDataReader As OdbcDataReader = _
0556:                     tOdbcCommand.ExecuteReader(CommandBehavior.SequentialAccess)
0557:             While (tOdbcDataReader.Read())
0558:                 tStringBuilder.Append(tOdbcDataReader.GetString(0) & vbCrLf)
0559:             End While
0560:             tOdbcConnection.Close()
0561:         Catch pException As Exception
0562:             MessageBox.Show(pException.Message)
0563:         End Try
0564:         Return tStringBuilder.ToString()
0565:     End Function
0566:     Public Function Size() As Integer
0567:         Dim tNumRows As Integer = 0
0568:         Dim tSQLString As String = "SELECT number FROM vehicles"
0569:         Console.WriteLine(tSQLString)
0570:         Dim tOdbcConnection As OdbcConnection = _
0571:                 New OdbcConnection(iConnectionString)
0572:         Dim tOdbcCommand As OdbcCommand = _
0573:                 New OdbcCommand(tSQLString, tOdbcConnection)
0574:         Try
0575:             tOdbcConnection.Open()
0576:             Dim tOdbcDataReader As OdbcDataReader = _
0577:                     tOdbcCommand.ExecuteReader(CommandBehavior.SequentialAccess)
0578:             While (tOdbcDataReader.Read())
0579:                 tNumRows += 1
0580:             End While
0581:             tOdbcConnection.Close()
0582:         Catch pException As Exception
0583:             MessageBox.Show(pException.Message)
0584:         End Try
0585:         Return tNumRows
0586:     End Function
0587: End Class

The above code uses the Open Database Connectivity .NET Data Provider. In order to use ODBC, you will need to install an ODBC driver. As the above code connects to a MySQL server, I installed the MyODBC driver, onto the laptop from which I was running VB.NET.