2009-12-03 4 views
3

Nous avons un modèle de facture qui facture les clients de différentes façons. Par souci de brièveté, je vais me concentrer sur deux: le coût par impression et le coût par téléphone. Ma pensée était de mettre en œuvre ces stratégies (et le reste) et de les mélanger dynamiquement dans la classe de facturation.Modèle de stratégie pour les modèles de facturation qui utilisent des données différentes pour le calcul?

Cela semble approprié car il existe différentes sources d'informations utilisées pour déterminer le nombre d'impressions/d'appels. Cela pourrait être encapsulé dans la stratégie, tout en gardant la formule de base dans la classe Invoice.

Le calcul du coût par empreinte est simple: num impressions X cost per impression.

Le calcul pour les demandes téléphoniques est un peu plus compliqué: 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 

Ensuite, les modules peuvent être:

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 

Cependant, si un nombre d'appels ou non est basée sur la durée de l'appel et cela varie d'un modèle à. Ainsi, lorsque je cherche dans les journaux du téléphone, j'ai besoin d'avoir cette valeur.

Ma question est où cette valeur est-elle stockée? Je pourrais créer une stratégie pour les factures basées sur des appels de 10 secondes et une autre pour les factures de 30 secondes, mais cela semble inutile. Si un accord est intervenu pour que le seuil soit de 15 secondes, j'ai besoin d'écrire une nouvelle stratégie. Quel est le meilleur choix de conception pour résoudre ce problème?

Répondre

0

Vous pouvez récupérer tous les modules mixtes et la classe de base à l'aide de la méthode de classe ancestors. Donc, si vous avez une instance myInvoice, vous pouvez simplement utiliser myInvoice.class.ancestors. Il renvoie un tableau de constantes afin que vous puissiez vérifier l'inclusion. Par ailleurs, dans ce contexte, je pense que la composition/agrégation traditionnelle est plus appropriée dans ce cas: elle est plus sûre lorsque plusieurs stratégies différentes coexistent en même temps. Vous ne voulez pas finir par changer la stratégie de toutes les factures parce que vous avez affecté la classe de base ...

3

N'implémentez pas vos stratégies en tant que modules mixins. Implémentez-les comme des classes à part entière avec une méthode publique PerInquiryCalculation et injectez la bonne dans la classe Invoice en utilisant son constructeur. De cette manière, chaque classe de stratégie peut avoir ses propres variables d'état définies pendant la construction. Le constructeur de PerInquiryStrategy peut prendre un seuil de durée que la méthode PerInquiryCalculation utilise pour calculer les frais.

Questions connexes