Pourquoi utiliser de préférence des collections de première classe?

15

Selon la règle numéro 4 de Object Calisthenics de Jeff Bay (RTF) dans The ThoughtWorks Anthology, il est recommandé de " Utiliser des collections de première classe ".

Règle 4: Collections de première classe

L'application de cette règle est simple: toute classe qui contient une collection ne doit contenir aucune autre variable membre. Chaque collection est enveloppée dans sa propre classe, donc maintenant les comportements liés à la collection ont une maison. Vous pouvez constater que les filtres font partie de cette nouvelle classe. De plus, votre nouvelle classe peut gérer des activités telles que la jonction de deux groupes ou l'application d'une règle à chaque élément du groupe.

Ce que je pouvais comprendre de cela était que nous devrions utiliser une classe distincte enveloppant la collection et avec des méthodes pour ajouter, supprimer, modifier les données de cette collection.

et nous en avons besoin pour être sûrs du type de données qui entre dans la collection et de ce qui en sort.

Dans le cas où nous utilisons une collection générique (dans les langues où elle est applicable), devons-nous suivre cette règle?

Si je manque une signification importante, veuillez clarifier.

Amogh Talpallikar
la source
1
Amogh Talpallikar J'ai changé la règle 8 en règle 4, car la règle 8 est en fait "Aucune classe avec plus de deux variables d'instance".
yannis
Il semble dire la Règle 8 dans la table des matières, puis l'appeler Règle 4 dans le corps.
inutile
6
Est-ce juste moi ou cette règle est-elle inapplicable telle qu'elle est écrite? Je veux dire, vous avez une classe avec une collection dedans, donc vous enlevez tout le reste. Maintenant, votre classe est une collection. Donc, si vous avez une autre classe, avec cette classe, elle contient une collection et ... faites mousser, rincer, répéter.
mjfgates
@mjfgates: hmm ... Excellent point! quelque chose à penser vraiment!
Amogh Talpallikar

Réponses:

12

La sécurité des types est une raison très mineure d'utiliser des collections de première classe. Depuis votre lien:

Règle 4: collections de première classe L'application de cette règle est simple: toute classe qui contient une collection ne doit contenir aucune autre variable membre. Chaque collection est enveloppée dans sa propre classe, donc maintenant les comportements liés à la collection ont une maison. Vous pouvez constater que les filtres font partie de cette nouvelle classe. De plus, votre nouvelle classe peut gérer des activités telles que la jonction de deux groupes ou l'application d'une règle à chaque élément du groupe.

L'idée ici est que si vous vous trouvez à rechercher, filtrer, valider ou quoi que ce soit au-delà d'ajouter / supprimer / itérer la sémantique d'une collection, le code vous demande de la mettre dans sa propre classe. Si vous devez mettre à jour une seule valeur (après une recherche), cela va probablement dans la classe de collection.

Le raisonnement est assez simple, les collections ont tendance à se faire circuler. Bientôt, 4 classes différentes ont leur propre SearchByID()méthode. Ou vous obtenez des valeurs de retour comme Map<Integer, String>avec le contexte de ce qui est stocké dans cette carte retiré. Une collection de première classe est une solution simple qui coûte un seul fichier source. En pratique, une fois ceux-ci en place (ils sont également très faciles à écrire pour les tests unitaires), tout changement concernant la collection est facile à gérer, comme quand il SearchByIDfaut prendre un GUID au lieu d'un int.

Steve Jackson
la source
8

... utiliser une classe distincte enveloppant la collection et avec des méthodes pour ajouter, supprimer modifier les données de cette collection

Cela fait bien plus que garantir le type des objets stockés dans les collections, il garantit également tous les invariants de collection.

Les arbres (rouge-noir, AVL, etc.) sont sensibles à l'ordre et leur comportement dépend du rééquilibrage, le cas échéant. Les performances de la table de hachage dépendront également du ré-hachage approprié. Voulez-vous vous rappeler de vérifier le facteur de charge à chaque fois que vous insérez dans une carte de hachage?

FWIW, le texte est assez clair à ce sujet (et je vais éditer le tout dans votre question, donc personne d'autre n'a besoin de télécharger ce RTF):

Chaque collection est enveloppée dans sa propre classe, donc maintenant les comportements liés à la collection ont une maison

Rien à voir avec les types (ou donc les génériques), tout à voir avec l'association du comportement de la collection à ses données.

Inutile
la source
1

La réponse simple est "Non" si vous utilisez un langage prenant en charge les génériques. Parce qu'il n'est pas nécessaire de vérifier le type car la fonctionnalité de langage elle-même fait un très bon travail à ce sujet (d'après mon expérience des génériques Java).

Mais si vous avez une situation où vous souhaitez personnaliser la structure de données donnée à partir du langage, vous pouvez créer une classe wrapper autour de la structure de données d'origine et exposer vos propres API et toujours utiliser l'implémentation sous-jacente de la structure de données d'origine.

java_mouse
la source
Je pense également dans les mêmes lignes. mais il devrait y avoir quelque chose, les exemples que j'ai vus pour cela étaient en Java et C # et les deux prennent en charge les collections génériques.
Amogh Talpallikar
@AmoghTalpallikar: Mon but était de rester simple. Sauf si je n'ai pas besoin de remplacer un comportement spécifique de la structure de données, je ne personnaliserai pas.
java_mouse