在软件设计工厂模式中使用抽象泛型类

时间:2012-11-07 15:10:56

标签: vb.net generics abstract-class factory-pattern

嘿伙计我有点设计问题。我创建了一个速率计算器,如下所示:

Public Interface ICalculator
 Property PaymentTerm As Double
 Function Calculate() As CommissionValues
 ReadOnly Property CalculationRule As CalculationRuleEnum
End Interface

Public Interface IFlexibleRateCalculator
 Inherits ICalculator
  Property TransferRate As Decimal
End Interface

Public Interface IFixedRateCalculator
 Inherits ICalculator
  Property ContractRate As Decimal
End Interface

Public Interface IRateSettingBase
  Property RateType As RateTypeEnum
  ReadOnly Property Calculator As ICalculator
End Interface

Public MustInherit Class RateSetting
 Implements IRateSettingBase
  Public MustOverride ReadOnly Property Calculator() As ICalculator Implements IRateSettingBase.Calculator

我可以这样做:

dim ratevalues as RateValues = RateSetting().Calculator.Calculate()

非常简单。问题是每种类型的计算器都有自己的属性集,需要设置它们才能使Calculate()方法正常工作。 所以我最终必须实现如下

FlexibleRateCalculator
Implements IFlexibleRateCalculator
    Private mRequestedRate As Decimal
    Public Function Calculate() As RateValues Implements ICalculator.Calculate

FixedRateCalculator
 Implements IFixedRateCalculator
    Private mTransferRate As Decimal
    Public Function Calculate() As RateValues Implements ICalculator.Calculate

使用泛型和抽象类创建工厂模式以动态生成特定类型的计算器的最佳方法是什么?

我需要一个非常通用的解决方案,因为许多计算速率将被添加和修改所有计算逻辑所需的参数。我希望能够快速完成此操作并可能通过db控制这些速率计算。欢迎使用C#或VB.Net的FYI答案:) 提前谢谢!

2 个答案:

答案 0 :(得分:0)

您熟悉任何IoC容器吗?您应该能够使用它们提供的工厂类型服务,根据给定的类型(枚举,字符串等)生成具有适当参数/属性的相应类型。

如果没有,您可以创建一个工厂类,该工厂类具有基于参数生成适当类型的方法。此方法可以接受ParamArray或其他对象,其中包含正确设置计算器所需的属性,然后通过ICalculator接口将其返回。

答案 1 :(得分:0)

仅保留ICalculator接口并将更具体的接口转换为类。我想不出为什么你要创建一个只是为了存储变量的一个很好的理由,所以我将完全摆脱RateSetting

Public Interface ICalculator
    Property Rate As Double
    Property PaymentTerm As Double
    Function Calculate() As CommissionValues
    ReadOnly Property CalculationRule As CalculationRuleEnum
End Interface

Public Class FlexibleRateCalculator : Implements ICalculator

    Public Sub New(rate As Double)
        Me.Rate = rate
    End Sub

    '
    ' ICalculator implementation goes here
    '

End Class

Public Class FixedRateCalculator : Implements ICalculator

    Public Sub New(rate As Double)
        Me.Rate = rate
    End Sub

    '
    ' ICalculator implementation goes here
    '

End Class

Public Enum RateType
    Flexible = 1
    Fixed = 2
End Enum

Public Class CalculatorFactory

    Public Shared Function GetCalculator(rate As Double, type As RateType) As ICalculator
        Select Case type
            Case RateType.Flexible
                Return New FlexibleRateCalculator(rate)
            Case RateType.Fixed
                Return New FixedRateCalculator(rate)
            Case Else
                Throw New ArgumentException
        End Select
    End Function

End Class

您可以通过将费率和费率类型传递给GetCalculator方法来创建对象实例。我不知道CalculationRule你的意思,但如果它对最终用户很重要,那么你应该将它作为附加参数添加。

您可以轻松添加更多实现ICalculator的计算器类型,只要您不要忘记在工厂方法中更新select语句。

编辑:当然,您还可以在返回对象实例之前设置其他属性。然而,这种模式的要点是确保最终用户不需要知道如何实现Calculate()。如果你想为每个计算器制作更具体的工厂方法,那就有点失败了。