Mon patron m'a donné un projet avec une logique particulière. Je dois développer une page Web qui doit guider le navigateur à travers de nombreux cas jusqu'à ce qu'il arrive au produit.
Voici le schéma des chemins de navigation dans le site:
IMPORTANT!
Dans la page Produits, le navigateur peut choisir le filtre qu'il souhaite.
- Si A, il / elle DOIT passer par le B (puis C bien sûr) ou C et atteindre les produits.
- Si B, il / elle DOIT passer par le C et atteindre les produits.
- Si C, il accède directement aux produits.
Bien sûr, si je pars de l'IA, je suis sur le chemin le plus long et quand j'atteins mes produits, j'ai 3 filtres actifs.
Jusqu'à présent, j'ai développé le code suivant qui fonctionne bien.
if filter_A
if filter_B
filter_C()
.. else ..
else
filter_C
.. else ..
else
if filter_B
filter_C()
.. else ..
else
filter_C()
.. else ..
Je suis ici pour demander ce qu'aurait fait un programmeur plus expert dans cette situation. Je n'ai pas respecté le principe DRY, je ne l'aime pas et j'aimerais connaître une alternative pour développer ce type de logique.
J'ai pensé à diviser chaque section de code en fonctions, mais est-ce une bonne idée dans ce cas?
la source
filter_C
, mais les instructions conditionnelles indiquent que le flux de contrôle peut circulerfilter_C
. Estfilter_C
facultatif?Réponses:
Vous n'avez pas dit si les filtres prenaient des paramètres. Par exemple, il
filter_A
peut s'agir d'un filtre de catégorie, de sorte qu'il ne s'agit pas seulement de "dois-je postulerfilter_A
", il peut s'agir de "je dois postulerfilter_A
et renvoyer tous les enregistrements avec le champ de catégorie =fooCategory
".La façon la plus simple de mettre en œuvre exactement ce que vous avez décrit (mais assurez-vous de lire la deuxième moitié de la réponse ci-dessous) est similaire aux autres réponses, mais je n'aurais aucune vérification booléenne du tout. Je définirais interfaces:
FilterA, FilterB, FilterC
. Ensuite, vous pouvez avoir quelque chose comme (je suis un programmeur Java, donc ce sera la syntaxe Java-esque):Ensuite, vous pouvez avoir quelque chose comme ça (en utilisant le modèle enum singleton de Effective Java ):
Mais si vous souhaitez réellement filtrer certains éléments, vous pouvez plutôt fournir une instance d'une
FilterA
implémentation qui fait réellement quelque chose. Votre méthode de filtration sera très simpleMais je ne fais que commencer.
Je soupçonne que l'
applyFilter
appel sera en fait assez similaire pour les trois types de filtres. Si c'est le cas, je ne le ferais même pas comme décrit ci-dessus. Vous pouvez obtenir un code encore plus propre en n'ayant qu'une seule interface, puis procédez comme suit:Ensuite, lorsque votre utilisateur navigue dans les pages, vous ajoutez simplement une nouvelle instance du filtre dont vous avez besoin, le cas échéant. Cela vous permettra d'appliquer plusieurs instances du même filtre avec des arguments différents si vous avez besoin de ce comportement à l'avenir, et également d'ajouter des filtres supplémentaires à l'avenir sans avoir à modifier votre conception .
De plus, vous pouvez ajouter quelque chose comme ce qui
NoOpFilter
précède ou vous ne pouvez tout simplement pas ajouter un filtre particulier à la liste, quoi que ce soit plus facile pour votre code.la source
Filter
commePredicate
vous pourriez l' utiliser directement dans l'Stream
API. De nombreux langages ont des constructions fonctionnelles similaires.Dans ce cas, il est important de séparer la logique du filtrage et le flux de contrôle du fonctionnement des filtres. La logique de filtrage doit être séparée en fonctions individuelles, qui peuvent fonctionner indépendamment les unes des autres.
Dans l'exemple de code affiché, il y a 3 booléens
filter_A
,filter_B
etfilter_C
. Cependant, à partir du diagramme,filter_C
s'exécute toujours, ce qui peut être changé en inconditionnel.REMARQUE: je suppose que le diagramme de flux de contrôle est correct. Il existe une différence entre l'exemple de code publié et le diagramme de flux de contrôle.
Un morceau de code séparé contrôle les filtres à exécuter
Il existe une séparation distincte entre le contrôle des filtres exécutés et leur fonction. Brisez ces deux morceaux de logique.
la source
Je suppose que vous voulez l'algorithme le plus simple et le plus clair.
Dans ce cas, sachant que le filtre c est toujours appliqué, je le vivrais hors de la logique if et l'appliquerais à la fin malgré tout. Comme il apparaît dans votre organigramme, chaque filtre avant le c est facultatif, car chacun d'eux peut être appliqué ou non. Dans ce cas, je vivrais des ifs séparés de chaque filtre, sans imbrication ni chaînage:
si vous avez un organigramme avec un nombre variable de filtres, avant celui obligatoire, je voudrais plutôt enregistrer tous les filtres dans un tableau, dans un ordre où ils devraient apparaître. Ensuite, traitez les filtres optionnels dans la boucle et appliquez celui obligatoire à la fin, en dehors de la boucle:
ou:
bien sûr, vous devrez définir le sous-programme de traitement du filtre.
la source
Je vais supposer que filterA, filterB et filterC modifient réellement la liste des produits. Sinon, si ce ne sont que des vérifications if, alors filterA et filterB peuvent être ignorés car tous les chemins mènent finalement à filterC. Votre description de l'exigence semble impliquer que chaque filtre réduira la liste des produits.
Donc, en supposant que les filtres réduisent réellement la liste des produits, voici un peu de pseudo-code ...
Dans vos besoins, filterC n'est pas appliqué automatiquement, mais dans le diagramme, il l'est. Si l'exigence est qu'au moins filterC doit être appliqué quoi qu'il arrive, alors vous appellerez applyFilter (filterC, produits) sans vérifier si filterC est choisi.
la source
Je me demande si la modélisation de vos filtres en une sorte d’objets dans un graphique aurait du sens. C'est du moins ce à quoi je pense en voyant le diagramme.
Si vous modélisez la dépendance des filtres comme un graphique d'objet, le code qui gère les chemins de flux possibles est à peu près simple sans aucune logique velue. En outre, le graphique (logique métier) peut changer, tandis que le code qui interprète le graphique reste le même.
la source