mardi 20 avril 2021

Factory method extension

I have a Project class that can be subclassed as MasterProject or SubProject. I am using the factory pattern to create instances of these classes. For this question, only MasterProject is important. Below is the ProjectFactory.vb file:

Public MustInherit Class ProjectFactory
    Protected MustOverride Function CreateProject(restResponse As Object) As Project
    Public MustOverride Function GetProject(restResponse As Object) As Project
End Class

Public Class MasterProjectFactory
    Inherits ProjectFactory

    Protected Overrides Function CreateProject(projectID As Object) As Project
        Return New MasterProject(projectID("Project_mpBaseProjectID_c"))
    End Function

    Public Overrides Function GetProject(projectID As Object) As Project
        Dim masterProject = CreateProject(projectID)

        Return masterProject
    End Function

End Class

Public Class SubProjectFactory
    Inherits ProjectFactory

    Protected Overrides Function CreateProject(restResponse As Object) As Project
        ' Do stuff
    End Function

    Public Overrides Function GetProject(restResponse As Object) As Project
        ' Do stuff
    End Function
End Class

Currently, a MasterProject is created using the restResponse object. If I wanted to have an option to create the MasterProject by passing either the whole restResponse object, or a single string, how would I go about it? I have a few ways in mind which I will share below, but I'm wondering which one is the most correct (following the factory pattern)?

#1

From what I saw and read about the factory design pattern, it is useful to have the GetProject method as in the example above so we can do any necessary manipulations before returning the project. Following that, I can check the type of the passed variable and call the corresponding CreateProject method that has a string overload and an object overload:

Public Class MasterProjectFactory
    Inherits ProjectFactory

    Protected Overrides Function CreateProject(projectID As Object) As Project
        Return New MasterProject(projectID("Project_mpBaseProjectID_c"))
    End Function

    Protected Overloads Function CreateProject(projectID As String) As Project
        Return New MasterProject(projectID)
    End Function

    Public Overrides Function GetProject(projectID As Object) As Project
        Dim masterProject As MasterProject

        If projectID.GetType() Is GetType(String) Then
            masterProject = CreateProject(projectID)
        Else
            masterProject = CreateProject(projectID)
        End If

        Return masterProject
    End Function
End Class

But the problem I see here is that I cannot differentiate which CreateProject method I'm calling. Maybe there's a way in VB.NET/C# to specify this, but I'm wondering if this is even a good practice?

#2

The second option that makes more sense to me would be to simply check the type of the passed argument projectID (restResponse in the first code block) and construct the object with it. I don't know if this is following the factory pattern.

Public Class MasterProjectFactory
    Inherits ProjectFactory

    Protected Overrides Function CreateProject(projectID As Object) As Project
        If projectID.GetType() Is GetType(String) Then
            Return New MasterProject(projectID)
        Else
            Return New MasterProject(projectID("Project_mpBaseProjectID_c"))
        End If
    End Function

    Public Overrides Function GetProject(projectID As Object) As Project
        Dim masterProject = CreateProject(projectID)

        Return masterProject
    End Function
End Class

I'd just like to point out that I know that there is no need to follow the pattern to the letter. Patterns are used situationally the best way they fit. I'm just looking for a general best practice rule to follow here.

Aucun commentaire:

Enregistrer un commentaire