我们有一个发票模型,可以用几种不同的方式向客户收费。为简洁起见,我将重点介绍两个:每次印象的成本和每次电话查询的成本。我的想法是将这些(以及其余的)作为策略实现,然后动态地将它们混合到invoice类中。
这似乎是适当的,因为有不同的信息源用于确定印象/呼叫的数量。这可以封装在策略中,同时将基本公式保留在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秒,我需要写一个新的策略。解决此问题的最佳设计选择是什么?
发布于 2009-12-04 13:25:50
不要将您的策略实现为模块混合。使用公共PerInquiryCalculation方法将它们实现为成熟的类,并使用Invoice类的构造函数将正确的类注入到该类中。
这样,每个策略类都可以在构造过程中设置自己的状态变量。PerInquiryStrategy的构造函数可以采用PerInquiryCalculation方法用来计算费用的持续时间阈值。
发布于 2009-12-03 15:43:16
您可以使用类方法ancestors检索所有混合的模块和基类。因此,如果你有一个实例myInvoice,你可以简单地使用myInvoice.class.ancestors。它返回一个常量数组,以便您可以检查是否包含。
顺便说一句,在这种情况下,我认为传统的组合/聚合在这种情况下更合适:当几种不同的策略同时共存时,它更安全。您不希望以更改所有发票策略结束,因为您影响了基类...
https://stackoverflow.com/questions/1837117
复制相似问题