web-dev-qa-db-fra.com

Existe-t-il un modèle de conception qui s'appliquerait aux modèles de remise?

Existe-t-il des modèles de conception connus pour implémenter des modèles de remise?

Par modèles de réduction, je veux dire ce qui suit:

  1. Si un client achète le produit X, le produit Y et le produit Z, il obtient une remise de 10% ou 100 $.

  2. Si un client achète 100 unités de produit X, il obtient une remise de 15% ou 500 $

  3. Si un client a apporté au cours de la dernière année plus de 100 000 $, il bénéficie d'une remise fixe de 20%

  4. Si un client a acheté 2 unités de produit X, il obtient 1 unité de produit X (ou produit Y) gratuitement.

  5. ...

Existe-t-il un modèle générique qui peut être appliqué pour gérer tous les scénarios ci-dessus? Je pense à quelques modèles, mais je n'arrive pas à en trouver un générique.

36
Kanini

Si le problème est que vous devez appliquer plusieurs remises, dans certaines circonstances, vous pouvez envisager le modèle Chaîne de responsabilité .

En un mot, vous transmettez les informations que vous souhaitez traiter au premier processeur, et il décide à partir de là de les transmettre à d'autres processeurs avant de renvoyer le résultat.

De cette façon, vous pouvez changer la structure et la séquence des processeurs sans jamais changer le code appelant.

18
pdr

La stratégie, le décorateur et les modèles d'état me semblent être des points de départ potentiels. L'état peut être particulièrement utile pour 2 ou 3, car 2 dépend de l'état de la commande et 3 dépend de l'état du client dans un délai. La stratégie et le décorateur se distinguent des autres, car vous pouvez utiliser la stratégie pour implémenter plusieurs algorithmes de calcul du prix de la commande et le décorateur pour ajouter de nouvelles remises à la commande.

Cependant, n'oubliez pas que les modèles de conception ne sont que des modèles. Il n'y a peut-être pas un seul modèle qui s'applique, mais plutôt un système de modèles. Pensez également à apporter des modifications aux modèles décrits pour les adapter mieux à votre solution. Il vaut mieux avoir un bon design que de forcer un motif où cela n'aide pas nécessairement juste pour le plaisir de dire que vous avez un motif.

11
Thomas Owens

Eh bien, je voudrais concevoir un modèle de remise en tant que paire "Précondition" et "Remise", où "Précondition" est une classe avec des méthodes

  bool IsFulfilled(Customer c);

ou et

  bool IsFulfilled(Customer c, Order o);

et Discount a une méthode void ApplyTo(Customer c). Cela vous donne la possibilité de combiner tout type de condition préalable avec tout type de remise (je pense que c'est une forme de "modèle de pont").

Si vous avez un nombre fixe de conditions préalables, vous pouvez résoudre le problème en créant des sous-types spécifiques (modèle de stratégie). Cependant, lorsque vos conditions préalables sont autorisées à être très complexes, avec des instructions logiques comme ET, OR et NON, vous pouvez mieux implémenter une sorte d'interpréteur de règles pour les conditions. Les règles peuvent être un simple chaîne de texte écrite dans un simple "langage spécifique au domaine".

Il en va de même pour la classe "Discount", vous pouvez avoir des sous-types pour différents types de remises, ou une approche générale où les règles de remise sont données sous forme de texte, évaluées par un interprète.

10
Doc Brown
  • Il faut probablement une interface IDiscount car toutes les différentes remises sont la même chose, et nous voudrons les traiter conceptuellement comme des remises génériques.

  • La classe "commande de ce client" a probablement besoin d'une collection de remises. Liste? Hacher? Liste liée? Je m'en fous encore. Des remises s'appliquent à l'achat, pas au client!

  • Gardez la construction de l'instance de remise distincte du client, du panier, de l'historique, etc. Cela changera beaucoup - comme l'a souligné @jfrankcarr.

  • Probablement une classe différente pour chaque remise car l'algorithme et les paramètres de chaque remise varient énormément et de manière imprévisible.

  • Je vois beaucoup de gestion d'événements car le calcul des remises répond aux modifications du panier d'achat et vice versa.

Application de modèle de conception

  • Je vois un strategy pattern. IDiscount est l'interface pour implémenter différents algorithmes de réduction.
  • Je vois un factory. Certainement pas un abstract factory pattern Complet, mais une seule classe à ce stade de l'analyse. Raisonnablement, il doit y avoir un seul endroit où il y a suffisamment de contexte pour décider quelles remises s'appliquent et ensuite les créer. Une classe. Si les règles d'application des remises explosent plus tard en raison d'une fête champignon du département Marketing, toute logique de construction de remises supplémentaire doit toujours fusionner dans cette classe d'usine de base, je pense.

  • Je peux voir Chain of Responsibility. Ce n'est pas mutuellement exclusif à l'idée factory. Au lieu d'itérer une collection de remises, chaque remise appelle le gars suivant. La classe "commande du client" ne contient pas de collection de remises dans ce cas.

  • Le facteur "hmmmm ...." dans la chaîne de responsabilité, je pense, est que chaque remise a une référence à la suivante. L'implication est que l'ordre est important. Ce qui n'est pas le cas. En outre, le concept incarné par le CoR est qu'un objet ne peut pas gérer la demande , il est donc transmis "jusqu'à la prochaine autorité supérieure". Notre modèle est différent. La seule demande est de calculer. Chaque remise fait cela. La sortie ou l'effet peut être nul mais chaque remise est calculée. Je me penche instinctivement vers une plus grande fidélité dans le monde réel.

Hypothèses

  • Les remises sont basées sur le panier d'achat actuel et/ou l'historique des achats
  • Aucun rabais ou plus peuvent s'appliquer. Il n'y a pas de rabais mutuellement exclusifs
  • Un calcul correct ne dépend pas de l'ordre dans lequel les remises sont appliquées.

Qu'est-ce qui change, qu'est-ce qui reste le même?

  • Les remises sont très différentes. Nombre et type de paramètres différents pour constituer chaque règle.

  • Les arguments en faveur des remises éligibles changent à mesure que le panier change.

  • Le nombre de remises disponibles change

  • Les remises accordées à ce client peuvent être modifiées à mesure que son panier change.

  • L'historique des achats ne change pas dans le contexte de cet achat

  • Le coût total évolue dynamiquement en fonction des lignes d'achat et des remises appliquées.

  • Après l'application initiale, la sortie d'une remise peut changer, comme la quantité d'achat change par exemple.

4
radarbob

Logiquement, un modèle de remise peut être n'importe quoi, vous ne pouvez donc pas supposer que vous pouvez programmer tous les cas à l'avance. Personne ne peut pas non plus être absolument sûr de ce dont vous avez réellement besoin. Cependant, en supposant que vous bénéficiez des types de remises habituels du monde réel ...

Une grande question est de savoir si les remises seront programmées ou si vous voulez que les utilisateurs les entrent. Comme mentionné ci-dessus, vous ne pouvez pas jamais les faire programmer, mais généralement le but est d'essayer de faire plus de saisie de données comme pour les cas courants, plutôt que de les programmer tous. Cela s'applique dans une certaine mesure même si des programmeurs sont utilisés pour créer toutes les remises.

Martin Fowler mentionne la "méthode d'instance individuelle" dans "Modèles d'analyse: modèles d'objets réutilisables" dans le cadre de la mise en œuvre des "règles de publication" pour les systèmes comptables, mais les règles semblent assez similaires aux vôtres. Je donnerais plus de détails mais c'est une œuvre protégée par le droit d'auteur et

Pour une interface utilisateur, vous devez soit proposer des cas d'utilisation assez simples, soit créer un interpréteur et un générateur de requêtes. Peut-être les deux, un pour les cas simples et un plus avancé. Si vous écrivez un interpréteur, c'est probablement un assez bon cas pour utiliser le modèle Interpreter, car il est relativement simple de coder par rapport à un générateur d'analyseur, et le temps d'analyse plus lent n'aura probablement pas vraiment d'importance. (Si vous aimez utiliser des générateurs d'analyseurs, ne me laissez pas vous arrêter).

N'essayez pas de tout faire avec un interprète - à un moment donné, vous ne faites que programmer dans votre propre langage minable, vous pouvez donc aussi bien en utiliser un réel. Si votre langage interprété prend en charge les fonctions (il devrait probablement permettre de les appeler - les définir est douteux) celles-ci peuvent être codées dans un vrai langage. N'allez pas plus loin dans cette voie que vous ne le devez.

Peu importe ce que vous faites, finalement, quelqu'un voudra que la remise soit basée sur le fait qu'il a acheté dans les 30 jours ouvrables suivant une promotion - où les jours ouvrables ne comptent que s'il n'y a pas de vacances dans la région définie par le code postal du magasin ou le client code postal. N'essayez donc pas de concevoir le système parfait à l'avance - supposez que vous devrez parfois écrire du code pour de nouveaux types de remises et concevoir en conséquence.

1
psr

Est-il utile de demander s'il existe un modèle utile pour cela? Quel type de schéma est requis - structurel ou comportemental?

Idéalement, si je devais écrire un logiciel pour cela, tout ce qu'il faudrait, c'est un algorithme . Une fonction simple qui calcule la remise totale comme suit:

cart.calculateDiscount(productVector);

Vous n'avez pas vraiment besoin de plus que cela!

Pour clarifier: je comprends qu'il y aura de nombreuses règles - la plus élémentaire d'une telle représentation devrait être sous la forme d'une base de règles (ensemble d'attributs de données et réduction résultante par rapport à elle) et la fonction telle que ci-dessus l'itérerait pour la calculer. Si des règles sont ajoutées ou supprimées, vous ne devriez pas changer le code, il suffit de changer la base de règles.

Le modèle ne sera requis que si nous avons besoin d'objets différents pour accéder aux API les uns des autres ou communiquer pour mettre une tâche en place.

PS: Pensez-y - lorsque le pare-feu traite les paquets et les transmet ou les rejette (ou les modifie) - quel modèle de conception utilise-t-il? La réponse est AUCUNE des réponses décrites ci-dessus!

0
Dipan Mehta