J'ai le scénario suivant où j'ai différents types d'algorithmes de vente pour calculer le prix de vente. Correctsalestrategy n'a pas besoin de paramètre de baseprice tandis que toutes les autres implémentations de stratégie en ont besoin. Y a-t-il un bon moyen d'éviter ce paramètre redondant?
6 Réponses :
Pas un bon, à mon avis. Je le garderais comme c'est. Il y a divers astuces que vous pouvez utiliser comme paramètres a > (avoir un seul paramètre double [] de prix) ou idynnamicObject code>. Mais le plus propre est juste d'avoir certaines stratégies ignorer le paramètre supplémentaire. P>
Si vous utilisez C # 4.0, vous pouvez em> pour inverser les paramètres et faire de Suivant peut être fait ... p> Notez que baseprice code> en option, comme:
montantoffsale code> 's
baseprice code> paramètre est pas EM> facultatif, ce qui signifie que ce qui suit ne compilera pas: p>
Je viens de taper dans cette même réponse; Puis a remarqué votre réponse alors que je vérifiais le code :-).
C'est une bonne idée, mais ce n'est pas évolutif.
non. Ce n'est pas un paramètre redondant; Le code qui utilise une salresstrategy ne doit pas savoir quelle classe concrete qu'il utilise, la signature de la méthode doit être identique dans toutes les classes dérivées. P>
Un bon moyen de supprimer les paramètres non pertinents d'une interface consiste à transmettre ces paramètres dans des constructeurs à partir de sous-classes. Donc, une alternative à votre conception serait la suivante: dans cette construction, vous ne polluez pas votre interface avec des données spécifiques des sous-classes. P> P>
Je pense que le problème de cette approche est que, à un moment donné, quelque chose doit créer une sous-classe code> salestrategy que B> doit connaître le point de base. Donc, cela déplace donc le paramètre supplémentaire de l'appel de méthode à la méthode d'usine. Il y aurait toujours un endroit où ce paramètre n'est pas utilisé.
Une autre alternative consiste à utiliser un objet Paramètres ou Le seul inconvénient est qu'un dictionnaire Dictionnaire
dictionnaire
Les dictionnaires sont trop non structurés pour être une bonne conception dans un cas avec des propriétés simples et bien définies, telles que la tarification - et pas très efficace non plus. Ils ont des applications telles que la configuration ou l'option pour des sous-modules complexes, ou une extensibilité très ouverte - mais sont préférables d'être utilisées au temps d'initialisation / de configuration, plutôt que tous les calculs.
Je suis d'accord - il s'agit du compromis entre les signatures de méthodes complexes, du code efficace, de la lisibilité, etc.
au cœur du modèle de stratégie est l'idée que le code d'appel ne connaît pas la mise en œuvre appelée. p>
Si vous deviez modifier les paramètres utilisés par implémentation, vous constaterez que vous n'obtenez pas le plein bénéfice de ce modèle: un appelant devrait savoir quelle implémentation allait être utilisée et comment l'appelait. P >
Ce que j'ai tendance à faire est de passer une classe qui contient une super série d'informations (quelque chose comme PriceInfo), qui est toujours peuplée de la même manière (idéalement centralisée dans le code) et la seule différence est la mise en œuvre de la stratégie. . P>
L'un des avantages est que je peux ajouter une propriété à ma classe de prixInfo qui n'était pas pertinente dans le passé (comme dites, systèmeDiscount) et l'impact sur le système dans son ensemble n'est pas trop grand. p>
Bon commentaire sur PriceInfo. Enroulant les informations de l'entité sous-jacente (par exemple de «produit» ou «commande») dans un prixInfo, permet également d'apporter davantage de types d'entités (frais d'expédition?) À apporter plus tard dans le système ..
Et un prix de prixInfo ou une interface «réponse» similaire permet également de mieux concentrer votre conception de l'API; sur 'Qu'est-ce que l'algorithme doit savoir ", plutôt que" Comment puis-je pirater cela des champs de mon entité actuelle ". Je trouve cela aide à nettoyer et à clarifier mon code, très efficacement.
Tout d'abord, changez vos paramètres vers
décimal code> au lieu de
double code>. jamais b> Utiliser des numéros de points flottants binaires pour traiter de la monnaie car ils ne peuvent pas représenter exactement les valeurs de devises, même des valeurs simples telles que
1.1 code> et des erreurs d'arrondi sont très importantes lors de la remise de l'argent des peuples. Voir: en.wikipedia.org/wiki/...