views:

37

answers:

2

Hi all

I am trying to re-write an existing system with objects. I have created a few basic objects but am stuck on exactly how to get them to work how I want.

These are the basic classes:

Public Class Course
    Public AcadPeriod As String
    Public AoSCode As String
    Public AoSPeriod As String
    Public Title As String

    Public Reviews As New Reviews
End Class

Public Class Courses
    Inherits CollectionBase

    Public Sub Add(ByVal cse As Course)
        List.Add(cse)
    End Sub
End Class

Public Class Review
    Public ReviewID As String

    Public Categories As Categories
End Class

Public Class Reviews
    Inherits CollectionBase

    Public Sub Add(ByVal rev As Review)
        List.Add(rev)
    End Sub
End Class

Public Class Category
    Public CategoryID As String
    Public CategoryName As String
    Public Comment As String
    Public MeasureValue As Integer
    Public CompletedBy As String
    Public CompletedDate As DateTime
End Class

Public Class Categories
    Inherits CollectionBase

    Public Sub Add(ByVal cat As Category)
        List.Add(cat)
    End Sub
End Class

What I want to be able to do is write code like the below:

Courses([CourseCode]).Reviews(1).Categories([CategoryID]).Comment or Courses(i).Reviews(1).Categories(x).Comment

Characters between [ and ] represent some value that will be coming from the calling application.

The second part of my question has to do with what is the best way to retrieve the data. Do I have all date retrieved internally by the object automatically upon instantiation (which could be quite a lot of data to retrieve), or have a method like GetReviews (within the Course object) or GetComments (within the Review object) which the application has to call before these objects become available? Should these methods simply fill in these objects within their parent object, or return the objects directly to the calling application?

However, I am going to want to retrieve the Courses object as some point. To me, it seems wrong to have this method in the Courses object itself ie. (Courses.GetCourses([StaffMember]))

I am really just trying to get in to programming OO, as I have used .Net in a very procedural manner up to now. Are there any books that anyone can recommend which act as a guide for how to use OO and the different ways to use it depending on the task at hand? I have created plenty of classes in the past which have always worked pretty well for me, but I struggle in working out how to put them all together in the best way possible.

+1  A: 

First part of your question: Yes you can do that and yes, you probably should in order to make your classes abstract. I like the pattern you're going for. What you'll do is make the classes have a constructor that receives the key. It will look like this:

Public Class Course
    Public AcadPeriod As String
    Public AoSCode As String
    Public AoSPeriod As String
    Public Title As String

    Public Reviews As New Reviews()

    Public Sub New(CourseCode As String)
        Dim myORM = New TheORM()
        Me.AcadPeriod = myORM.GetAcadPeriod(CourseCode)
        Me.AoSCode = myORM.GetAoSCode(CourseCode)
        ' And so forth for all the properties
    End Sub
End Class

... where "TheORM" is your object relational manager, like Linq-To-SQL or Entity Framework or NHibernate or one that you created yourself. It is your abstraction of grabbing data from the database.

Second part of your question: If you're reading from a database, the best practice is to read the data only when needed as long as the retrieving isn't time-sensitive and would take a long time. If the same data needs to be read multiple times, it is better to read it once when needed and cache it.

Rap
A: 

Another way of solving this problem is to have each class "have" or "contain" the other classes. This is called composition or aggregation in OO terminology and I consider it a more efficient design. However, you'll write this to read the data:

Courses.GetCourse([CourseCode]).Reviews.GetReview(1).Categories.GetCategory([CategoryID]).Comment

The classes would look like this:

Public Class Courses
    Public Courses As Dictionary(Of String,Courses)()
    Public Sub New()
        'Load your courses into Me.Courses here
    End Sub
    Public Function GetCourse(CourseCode As String) As Course
        Return Me.Courses(CourseCode)
    End Function
End Class
Rap
Thanks for your answers Rap, I think a combination of these two methods will be perfect for my problem.I have marked you as the answer, thank you very much.
hermiod