3

我有以下子类 CentreAddress 和 VenueAddress 从基本抽象类 BaseAddress 扩展而来。

我正在考虑实现一个简单的工厂 AddressFactory 来处理为我的 Center 和 Venue 类创建 CentreAddress 和 VenueAddress 的具体实例。

我的实现虽然不允许我在设计时为扩展的具体实例的属性赋值。

在运行时,正在创建正确的具体实例。

我可以更改 Centre.Address 和 Venue.Address 的返回类型——但这肯定会破坏让 AddressFactory 成为应用程序中唯一引用具体类的部分的优势吗?

我的实现是否正确和/或模式在这里不是很适合,即。试图在不需要时填充模式?代码如下。

谢谢

Sub Main()

    Dim centre1 = New Centre
    centre1.Name = "Centre 1"
    centre1.Address.Line1 = "Address Line 1"
    centre1.Address.Line2 = "Address Line 2"
    'centre1.Address.Line3 = "Address Line 3"  not allowed

    Dim venue1 = New Venue
    venue1.Name = "Venue 1"
    venue1.Address.Line1 = "Address Line 1"
    venue1.Address.Line2 = "Address Line 2"
    'venue1.Address.County.Name = "Bath and NE Somerset"  not allowed

End Sub

Public Class CentreAddress
    Inherits BaseAddress

    Public Property Line3 As String

End Class

Public Class VenueAddress
    Inherits BaseAddress

    Public Property County As County

End Class

Public Class County

    Public Property Name As String

End Class

Public Class Centre

    Private m_address As BaseAddress

    Public Property Name As String

    Public ReadOnly Property Address As BaseAddress
        Get
            If m_address Is Nothing Then
                m_address = AddressFactory.CreateAddress(Me)
            End If
            Return m_address
        End Get
    End Property

End Class

Public Class Venue

    Private m_address As BaseAddress

    Public Property Name As String

    Public ReadOnly Property Address As BaseAddress
        Get
            If m_address Is Nothing Then
                m_address = AddressFactory.CreateAddress(Me)
            End If
            Return m_address
        End Get
    End Property

End Class

Public Class AddressFactory

    Public Shared Function CreateAddress(objectType As Object) As BaseAddress

        If TypeOf objectType Is Venue Then
            Dim venueAddress As New VenueAddress With {.County = New County}
            Return venueAddress
        ElseIf TypeOf objectType Is Centre Then
            Return New CentreAddress
        Else
            Return New VenueAddress
        End If

    End Function

End Class
4

2 回答 2

1

拥有一个具有两种不同方法的工厂并没有错,每种方法都返回特定的派生类型。例如:

Public Class AddressFactory
    Public Shared Function CreateCentreAddress() As CentreAddress
        Return New CentreAddress()
    End Function

    Public Shared Function CreateVenueAddress() As VenueAddress
        Return New VenueAddress()
    End Function
End Class

通常,这正是您想要和需要的工厂类型。当派生的特定属性不适用时,您仍然具有可以编写通用代码以使用基地址的优势。例如:

Public Sub DoSomethingWithVenue()
    Dim venueAddress As VenueAddress = factory.CreateVenueAddress()
    venueAddress.County = New County()
    ' ...
    DoSomethingWithAnyAddress(venueAddress)
End Sub

Public Sub DoSomethingWithCentre()
    Dim centreAddress As CentreAddress = factory.CreateCentreAddress()
    centreAddress.Line3 = "my line 3"
    ' ...
    DoSomethingWithAnyAddress(centreAddress)
End Sub

Public Sub DoSomethingWithAnyAddress(address As BaseAddress)
    address.Name = "my name"
    ' ...
End Sub

但是,有时您确实需要工厂将对象作为基类型返回,但这仅适用于您有需要创建对象的通用代码,但并不关心正在创建的特定派生类型。看起来情况并非如此,所以我不会不必要地把自己画到角落里。如果您将来确实需要做类似的事情,您仍然可以通过创建重用原始工厂类的新工厂类来做到这一点:

Public Interface IAddressFactory
    Public Function CreateAddress() As BaseAddress
End Interface

Public Class VenueAddressFactory
    Implements IAddressFactory

    Private _factory As New AddressFactory()

    Public Function CreateAddress() As BaseAddress
        Return _factory.CreateVenueAddress()
    End Function
End Class

Public Class CentreAddressFactory
    Implements IAddressFactory

    Private _factory As New AddressFactory()

    Public Function CreateAddress() As BaseAddress
        Return _factory.CreateCentreAddress()
    End Function
End Class

Public Class CommonAddressBusiness
    Public Sub New(factory As IAddressFactory)
        _factory = factory
    End Sub

    Private _factory As IAddressFactory

    Public Sub DoSomething()
        Dim someTypeOfAddress As BaseAddress = _factory.CreateAddress()
        ' ...
    End Sub
End Class
于 2013-05-15T13:17:59.320 回答
-1

为什么不使用受保护的 MustOverride 函数 CreateAddress() 从公共基类派生 Center 和 Venue?您只需在相应的派生类中重写此函数。您甚至可以通过使用new关键字覆盖它来更改 Address 属性的类型。在我看来,不需要工厂模式。除此之外,我看不出有什么不妥。

于 2013-05-15T13:02:59.097 回答