Question

Imaginez le type d’application typique dans lequel vous avez une liste d’éléments avec des propriétés différentes. Par exemple. une vue arborescente contenant 100 éléments, chacun portant un nom , un classement , un classement parmi les éléments les plus recherchés de la planète etc. Il existe probablement aussi des relations multiples entre plusieurs éléments et catalogues d'éléments , ou entre éléments et item-creators etc. etc.

Maintenant, cette application a naturellement besoin d’un système de filtrage. Par exemple. où je peux construire des filtres complexes avec de multiples conditions de toutes sortes, entre des données dans des relations différentes.

La tâche de conception consistant à écrire une telle fonctionnalité de filtrage devrait être quelque chose que BEAUCOUP de développeurs ont fait et il doit sûrement exister un type de modèle de conception le mieux adapté à la tâche.

Quelqu'un?

Modifier: sur le wiki de la communauté, car je soupçonne qu'aucun modèle de facteur de l'industrie n'est utilisé pour cela. Question trop générale, je suppose.

Était-ce utile?

La solution

Il est un peu difficile de préciser ce que vous voulez, je vais donc prendre mes propres hypothèses.

  1. La collection sous-jacente doit rester inchangée après le filtrage
  2. Le résultat n'est pas persistant

Une approche classique consiste à utiliser des vues . Il s’agit essentiellement de programmation paresseuse , dans laquelle vous créez un objet pouvant accéder à la collection d'origine et connaissant le filtre à appliquer mais ne faisant aucun calcul tant que rien n'est requis.

Dans les collections, les vues sont souvent implémentées avec des itérateurs , et pour le filtrage, bien sûr, un modèle de stratégie, comme indiqué précédemment.

Par exemple:

Collection myCollection;
Predicate myFilter;

// Nothing is computed here
View<Predicate> myView(myCollection, myFilter);

// We iterate until we find the first item in the collection that satisfies
// the Predicate, and no more, to initialize `begin`
View<Predicate>::Iterator begin = myView.begin(), end = myView.end();

L’avantage net est que si vous n’avez (par exemple) besoin que des 10 premiers éléments, vous appliquerez le prédicat autant que nécessaire pour trouver ces 10 premiers éléments, sans plus.

De plus, il n'y a pas de copie des éléments impliqués et votre vue sera mise à jour même si vous modifiez myCollection , bien que cela puisse affecter la validité des itérateurs (comme d'habitude).

Le problème est que (sauf si vous implémentez la mise en cache), le résultat est calculé à chaque fois.

Si vous souhaitez un résultat plus persistant, vous feriez mieux de créer une nouvelle collection contenant uniquement les éléments filtrés (ou leurs références). Il n’ya pas de schéma général ici car cela dépend de la manière dont vous voulez utiliser la liste "filtrée".

Comme pour le modèle de stratégie suggéré, vous pouvez généralement construire votre filtre par bloc à l'aide du modèle composite, puis transmettre l'objet ainsi construit en tant que stratégie.

Le modèle composé est particulièrement adapté pour représenter le résultat d'une expression analysée. Par exemple, vous pouvez consulter les arborescences d'expressions pour avoir une idée.

Autres conseils

Je ne connais pas de modèle de conception, mais vous pouvez examiner certaines des méthodes de tri sélectionnées. Il serait utile que vous en expliquiez certaines et expliquaient pourquoi vous ne les aimiez pas. à titre d'exemple.

Par exemple, LINQ dispose d’un bon moyen de trier en utilisant les arbres d’expression.

Vous pouvez également consulter le tri effectué dans les langages fonctionnels, dans lequel vous pouvez passer la fonction pour effectuer le tri, plutôt que de coder en dur un tri particulier.

Si vous travaillez avec du javascript, la fonction de tri peut être créée à la volée.

J'aime le filtre avec le prédicat de Collections Google et je mettrais en œuvre quelque chose de très similaire si je ne pouvais pas l’utiliser. Vous voudrez peut-être vérifier cette réponse à une question similaire pour un exemple d'implémentation. L'implémentation est en Java, mais vous verrez le motif.

Vous recherchez une base de données relationnelle à partir de laquelle vous pouvez utiliser SQL. Vous pouvez en installer une complète et vous y connecter à partir de votre application, ou vous pouvez faire quelque chose entre une base de données complète et des objets droits. En Java, par exemple, vous pouvez utiliser une base de données en mémoire telle que HSQLDB / JavaDB et utiliser les fonctions de celle-ci. Vous pouvez également utiliser JoSQL pour vous permettre d'opérer en SQL directement sur vos objets sans la base de données.

Autrement, si vous souhaitez programmer vous-même la chose, commencez par conserver 2 copies de vos données. L’un est votre ensemble complet de données, l’autre votre vue après filtrage. Ensuite, vous créeriez un index sur vos données pour chaque colonne, en triant les données et en conservant leur position dans la liste triée. La même configuration fonctionne pour une correspondance de filtre. Si quelque chose correspond à un filtre pour une colonne, donnez-lui un 1 ou 0 sinon. Ensuite, lorsque quelqu'un bascule l'ordre de tri, vous copiez vos données de la liste complète dans la liste des vues, ou lorsque vous modifiez les informations de filtre, vous ne prenez que les données qui correspondent.

Si ces relations sont exprimables en tant que RDF et OWL, vous pouvez utiliser un outil avec un noeud final SPARQL (tel que Jena) ou un raisonneur tel que Pellet. Mais sans plus de détails, il n’est pas clair que c’est la meilleure approche.

Voir si le http://en.wikipedia.org/wiki/Criteria_Pattern peut aider vous. Est basé sur le modèle de spécification

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top