【问题标题】:Strategy pattern for billing models that use different data for the calculation?使用不同数据进行计算的计费模型的策略模式?
【发布时间】:2010-12-22 16:01:45
【问题描述】:

我们有一个发票模型,可以通过几种不同的方式向客户收费。为简洁起见,我将重点关注两个:每次展示费用和每次电话查询费用。我的想法是将这些(以及其他)作为策略实现,然后将它们动态地混合到发票类中。

这似乎是合适的,因为用于确定展示次数/调用次数的信息来源不同。这可以封装在策略中,同时将基本公式保留在Invoice 类中。

每次展示费用的计算很简单:num impressions X cost per impression

电话查询的计算稍微复杂一点:num calls X cost per call

class Invoice
  def self.strategy
    self.class_eval <<-EOS
    include #{billing_type}
    EOS
  end

  def invoice_amount
    # this will used the module mixed in above
    self.rate * calculate_impressions
  end
end

那么,模块可以是:

module PerImpressionCalculation
  def calculate_impressions
     # get the number of impessions from source a...
  end
end

module PerInquiryCalcuation
  def calculate_impressions
     # get the number of impessions from source b...
  end
end

但是,通话是否重要取决于通话的时长,并且因型号而异。因此,当我搜索电话日志时,我需要有这个值。

我的问题是这个值存储在哪里?我可以为基于 10 秒调用和单独一个 30 秒调用的发票创建策略,但这似乎很浪费。如果达成的交易希望阈值为 15 秒,我需要编写一个新策略。解决此问题的最佳设计选择是什么?

【问题讨论】:

    标签: ruby oop design-patterns strategy-pattern


    【解决方案1】:

    不要将您的策略​​实现为模块混合。将它们实现为具有公共 PerInquiryCalculation 方法的完整类,并使用其构造函数将正确的类注入到 Invoice 类中。

    这样每个策略类都可以在构造过程中设置自己的状态变量。 PerInquiryStrategy 的构造函数可以采用PerInquiryCalculation 方法用来计算费用的持续时间阈值。

    【讨论】:

      【解决方案2】:

      您可以使用类方法ancestors 检索所有混合模块和基类。所以如果你有一个实例myInvoice,你可以简单地使用myInvoice.class.ancestors。它返回一个常量数组,以便您检查是否包含。

      顺便说一句,在这种情况下,我认为传统的组合/聚合在这种情况下更合适:当几种不同的策略同时共存时更安全。您不想因为影响了基类而最终更改所有发票策略...

      【讨论】:

        猜你喜欢
        • 2011-09-30
        • 1970-01-01
        • 1970-01-01
        • 2011-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-21
        • 2013-11-06
        相关资源
        最近更新 更多