Demand loading a new object from parameters

keb1965

Well-known member
Joined
Feb 9, 2009
Messages
103
Programming Experience
10+
I have a class that uses several other objects that are built from data out of the database. Each of these objects may or may not be needed at any given time, therefore, instead of loading dozens of objects when the person object is instantiated, I want to load the objects when the user calls the ReadOnly property of the person class. (This isn't really my class, so look beyond the naming and relationships). I am posting this strictly to get feedback and to provide others ideas on how to demand load objects when they have multiple objects that use the same constructor signature .. or it could be modified to use a parameter array and then the various constructors could parse it.

Consider this:
VB.NET:
Public Class Person

    Private _intPersonID As Integer = 0
    Private _objFather As Father = Nothing
    Private _objMother As Mother = Nothing
    Private _dtBirthdate As DateTime = Nothing
    Private _strName As String = ""
    Private _intFatherID As Integer = 0
    Private _intMotherID As Integer = 0
    Private _dataLayer As Datalayer
    Private _hasChanges As Boolean = False
    Private _isNew As Boolean = False
    
    'Instantiate a new person without any values
    Public New(ByVal datalayer As Datalayer)
        _datalayer = datalayer
        _isNew = True
    End Sub

    'Instantiate our person by reading the person's info from the database
    Public New(ByVal _datalayer As Datalayer, ByVal PersonID As Integer)
        _dataLayer = datalayer
        Dim lDt As Datatable = _dataLayer.load_Person(PersonID)
        If (lDt IsNot Nothing AndAlso lDt.Rows.Count > 0) Then
            Dim dRow As DataRow = lDt.Rows.Item(0)
            _intPersonID = CInt(dRow("intPersonID"))
            _strName = dRow("strName").ToString
            _dtBirthdate = CDate(dRow("dtBirthdate"))
            _intFatherID = CInt(dRow("intFatherID"))
            _intMotherID = CInt(dRow("intMotherID"))
        End If
    End Sub

    Public Property Name()As String
        Get
            Return _strName
        End Get
        Set(ByVal value As String)
            _hasChanges = (_strName <> value Or _hasChanges)
            _strName = value
        End Set
    End Property

    Public Property Birthdate()As DateTime
        Get
            Return _dtBirthdate
        End Get
        Set(ByVal value As DateTime)
            _hasChanges = (_strBirthdate <> value Or _hasChanges)
            _dtBirthDate = value
        End Set
    End Property

    Public Property MotherID()As Integer
        Get
            Return _intMotherID
        End Get
        Set(ByVal value As Integer)
            _hasChanges = (_intMotherID <> value Or _hasChanges)
            _objMother = Nothing
            _intMotherID = value
        End Set
    End Property

    Public Property FatherID()As Integer
        Get
            Return _intFatherID
        End Get
        Set(ByVal value As Integer)
            _hasChanges = (_intFatherID <> value Or _hasChanges)
            _objFather = Nothing
            _intFatherID = value
        End Set
    End Property

    'Return the demand loaded Mother object
    Public ReadOnly Property Mother() As Mother
        Get
            If (_objMother Is Nothing AndAlso _intMotherID > 0) Then
                Return CType(DemandLoad(intMotherID, GetType(Mother)), Mother)
            End If
        End Get
    End Property

    'Return the demand loaded Father object
    Public ReadOnly Property Father() As Father
        Get
            If (_objFather Is Nothing AndAlso _intFatherID > 0) Then
                Return CType(DemandLoad(intFatherID, GetType(Father)), Father)
            End If
        End Get
    End Property

    'Other properties will retrieve other structured objects using the passed type constructor and the ID of the item in the database.
    Private Function DemandLoad(ByVal value As String, ByVal t As Type) As Object
        Return t.GetConstructor(New System.Type() {GetType(Datalayer), GetType(String)}).Invoke(New Object() {_dataLayer, value})
    End Function

    'Add or Update our object if it is changed (save some CPU time if it isn't)
    Public Function Save() As Boolean
        'Always assume the Add/Update operation will fail
        Dim Success As Boolean = False
        If (_hasChanges AndAlso _isNew = False) Then
            'The save_Person method would return a boolean to indicate if the save was successful
            Success = _datalayer.save_Person(_intPersonID, _strName, _dtBirthdate, _intMotherID, _intFatherID)
        ElseIf (_hasChanges AndAlso isNew) Then
            Dim intNewPersonID As Integer = -1
            'The add_Person method would return the ID of the newly added person
            intNewPersonID = _datalayer.add_Person(_strName, _dtBirthdate, _intMotherID, _intFatherID)
            If (intNewPersonID > -1) Then
                _intPersonID = intNewPersonID
                _isNew = False   'Its saved now so it is no longer new
                Success = True
            End If
        End If
        Return Success
    End Function

End class

I would like some feedback on doing this. My current project requires 8 different objects, all of which may or may not be needed at any given time. Demand loading should save not only clock cycles but memory overhead as well.
 
Top Bottom