6 votes

Champs d'attributs et carte attributs-valeurs

J'ai une classe (java) avec environ 10 attributs, beaucoup d'entre eux pouvant potentiellement rester non initialisé et sont non consulté pendant la durée de vie d'un objet.

C'est pourquoi j'envisage d'utiliser un Map<String,Object> comme une carte nom-attribut -> valeur-attribut au lieu d'un grand nombre de champs, afin d'économiser des ressources.
Je me demande maintenant s'il existe des règles officielles ou officieuses, quand et comment choisir l'une des possibilités décrites. Combien d'attributs une classe doit-elle avoir pour que je puisse envisager d'utiliser une telle carte ? Devrais-je l'utiliser tout court ?

Merci d'avance pour vos conseils/opinions à ce sujet.

3voto

Voo Points 11981

Bon, vous faites cela pour économiser de la mémoire, je suppose, car il est clair que vous n'économisez pas les ressources du CPU en accédant à une carte au lieu d'un champ. Alors voyons comment cela fonctionne : (en supposant une JVM 64bit sans oops compressés - ce qui est irréaliste mais ne devrait pas trop changer les résultats, vous pouvez le calculer vous-même facilement)

En principe, un champ en Java ne prendra jamais plus de 8 octets (la taille d'un mot pour les références). Cela signifie que pour votre classe avec 10 champs, en supposant qu'ils sont tous inutilisés, le mieux que nous puissions faire est de 8*10 octets = 80 octets.

Maintenant, vous voulez remplacer cela par un HashMap à la place - ce qui signifie que nous utilisons déjà 8 octets supplémentaires pour cela. De plus, le HashMap est toujours initialisé, ce qui entraîne les surcharges suivantes : 2 mots d'en-tête + référence + 3 ints + float + 1 tableau (2 mots d'en-tête, taille de 4 octets, 16 références par défaut) qui occupe 182 bytes de la mémoire.

Puis-je vous féliciter d'avoir économisé un énorme -110 bytes !

PS : Je pense que la plus petite valeur par défaut possible pour le backing array du hashset est 2, donc vous pourriez l'utiliser et vous en sortir à peu près à égalité. Mais dès que vous stockez des objets dans l'ensemble, vous obtenez une surcharge supplémentaire à partir des objets Wrapper utilisés par la classe. C'est donc une mauvaise idée.

1voto

twain249 Points 5292

Il ne s'agit pas de savoir combien d'attributs différents vous possédez, mais comment ils sont utilisés et ce qui est nécessaire. A Map permettra une plus grande flexibilité pour ne pas avoir d'attributs ou pour avoir des attributs différents pour des instances différentes ou pour ajouter des attributs plus tard (en ajoutant des choses à l'élément Map ). Mais si les attributs sont de types différents String, Integer, Doubles etc., il faudra faire le Map de type Object et de mouler toutes les valeurs lorsque vous les utilisez (beaucoup plus de travail pour vous).

1voto

Kent Points 71470

Je ne pense pas que la carte soit une bonne idée.

  • Du point de vue de l'OO, les champs sont des propriétés d'un type et de son sous-type. Pensez à l'héritage et au polymorphisme, comment pouvez-vous faire en sorte que la carte atteigne ces caractéristiques de l'OO ?

  • même si on parle de style de code, cela ne rend pas vos codes plus propres. Comment gérez-vous le casting de type ? la gestion des exceptions ? ces codes seraient bien plus que la déclaration de champ et les getter/setters (si vous en avez).

0voto

user949300 Points 7954

J'aime l'idée de la carte pour les attributs qui sont vraiment facultatifs et "non essentiels". Sinon, vous aurez besoin de tout un tas de sous-classes et/ou vous devrez toujours vérifier si vos getters sont nuls.

En ce qui concerne le typage, j'écris souvent du code en passant la valeur par défaut comme 2ème argument, et je l'utilise pour déterminer le type de retour, par ex.

  int getValue(String key, int defaultValue);
  double getValue(String key, double defaultValue);
  String getValue(String key, String defaultValue);

L'appelant, et non la carte, doit connaître le type. A vous de voir si vous aimez ce style...

Toutefois, pour les attributs qui sont "essentiels", je préfère les champs réels.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X