9
votes

Existe-t-il un bon moyen d'éviter le paramètre de méthode inutilisé dans certaines des sous-classes tout en appliquant un modèle de stratégie?

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? XXX


1 commentaires

Tout d'abord, changez vos paramètres vers décimal au lieu de double . jamais 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 et des erreurs d'arrondi sont très importantes lors de la remise de l'argent des peuples. Voir: en.wikipedia.org/wiki/...


6 Réponses :



2
votes

Si vous utilisez C # 4.0, vous pouvez pour inverser les paramètres et faire de baseprice en option, comme: xxx

Suivant peut être fait ... xxx

Notez que montantoffsale 's baseprice paramètre est pas facultatif, ce qui signifie que ce qui suit ne compilera pas: xxx


2 commentaires

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.



5
votes

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.


0 commentaires

0
votes

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: xxx

dans cette construction, vous ne polluez pas votre interface avec des données spécifiques des sous-classes.


1 commentaires

Je pense que le problème de cette approche est que, à un moment donné, quelque chose doit créer une sous-classe salestrategy que 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é.



0
votes

Une autre alternative consiste à utiliser un objet Paramètres ou Dictionnaire . De cette façon, vous pouvez consolider le nombre de paramètres sur chaque méthode et laisser de la place à des paramètres supplémentaires. Il existe une modification des exigences à l'avenir.

Le seul inconvénient est qu'un dictionnaire dictionnaire peut effectuer le suivi des paramètres plus difficiles dans votre code, où un objet de paramètres aura simplement toutes les propriétés que vous pouvez afficher dans votre code. .


2 commentaires

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.



6
votes

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.

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.

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. .

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.


2 commentaires

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.