2009-12-03 68 views
3

我們有一個發票模型,以幾種不同的方式向客戶開具賬單。爲了簡潔起見,我將重點介紹兩種:每次展示的費用和每次電話查詢的費用。我的想法是實施這些(和其他)作爲戰略,然後動態混合到發票類。計費模式的策略模式使用不同的數據進行計算?

這似乎是合適的,因爲用於確定展示次數/調用次數的信息有不同的來源。這可以包含在策略中,同時保持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秒,則需要編寫新策略。解決此問題的最佳設計選擇是什麼?

回答

0

您可以使用類方法ancestors檢索所有混合模塊和基類。所以如果你有一個實例myInvoice,你可以簡單地使用myInvoice.class.ancestors。它返回一個常量的數組,所以你可以檢查包含。

順便說一句,在這種情況下,我認爲在這種情況下傳統的組合/聚合更合適:當幾種不同的策略同時共存時更安全。您不希望因爲您影響基類而更改所有發票策略......

3

請勿將您的策略​​實現爲模塊mixins。使用公開的PerInquiryCalculation方法將它們作爲完整的類實現,並使用其構造函數將正確的類注入Invoice類。

這樣每個策略類都可以在施工過程中設置自己的狀態變量。 PerInquiryStrategy的構造函數可以採用PerInquiryCalculation方法用於計算費用的持續時間閾值。