Quelqu'un a-t-il un exemple spécifique d'utilisation du modèle Flyweight? [fermé]


21

J'ai étudié les modèles de conception et suis tombé sur le modèle de poids de mouche. J'ai essayé de voir des opportunités d'utiliser le modèle dans mes applications, mais j'ai du mal à voir comment l'utiliser. De plus, quels sont les signes qu'un modèle de poids de mouche est utilisé lorsque je lis le code d'autres personnes?

Selon la définition, il dit:

Utilisez le partage pour prendre en charge efficacement un grand nombre d'objets à grain fin.

Si je l'ai bien lu, les dictionnaires et les tables de hachage pourraient être des instances de poids volants, est-ce exact?

Merci d'avance.


7
Juste une petite anecdote sur les poids volants: j'ai déjà dû créer de gros fichiers Excel (jusqu'à 500k enregistrements, plus de 100 colonnes) avec une API tierce. Les styles des cellules sont devenus extrêmement gourmands en mémoire. Ainsi, chaque fois qu'un style était nécessaire, une table de hachage a été vérifiée si un style égal existait déjà et n'a fourni qu'une référence à ce style. Cette modification a rendu possible cette exportation. Maintenant, avoir autant de données dans Excel est une folie à mon avis. Mais les contrôleurs avaient leurs macros d'analyse qu'ils voulaient conserver.
Falcon

9
Commentaire: J'espère que les gens qui écrivent des livres et des articles sur les modèles et OO arrivent dans le monde réel du programmeur moyen et cessent d'utiliser l'anglais de style avocat!
NoChance

1
"J'ai dû créer de gros fichiers Excel (jusqu'à 500k enregistrements, plus de 100 colonnes)" - ce n'est pas beaucoup comparé à ce que certains traders sont capables de créer ;-)
quant_dev

Après avoir lu plusieurs de ces exemples, je pense que la compression des données en mémoire serait un excellent endroit pour mettre en œuvre cette technique. Merci pour l'aide!
Jeremy E

Les cellules de tableau dans GWT sont des masselottes.
user16764

Réponses:


19

Un exemple est dans les bibliothèques Java. Java a des types primitifs (par exemple int, qui est un entier 32 bits) et des wrappers pour eux (par exemple Integer, qui encapsule int). Il existe des méthodes pour " encadrer " un intdans un Integeret déballer un Integerdans un int. Les wrappers sont nécessaires car les types primitifs ne sont pas des objets et ne peuvent donc par exemple pas être utilisés comme clés dans Maps ou placés dans Collections.

La méthode de boxe utilise un tableau d'objets flyweight comme une sorte de cache pour les Integers correspondant aux intvaleurs comprises entre -128 et 127. Comme ce sont les valeurs les plus susceptibles d'être utilisées comme clés ou placées dans des collections, elle réduit l'allocation et l'utilisation de la mémoire. (S'il y a 5000000 Integers représentant la valeur 0 flottant, cela utilise 5000000 fois plus de mémoire que la réutilisation de l'instance flyweight).



1
Ainsi, le pool de stagiaires pour les chaînes en C # est un autre exemple du modèle de poids mouche correct?
Jeremy E

1
@ Jeremy E: Oui, à mon avis, vous pouvez appeler string interning une application du modèle flyweight, même pour les chaînes, il ne s'agit pas seulement de consommation de mémoire, mais aussi d'efficacité d'exécution.
Falcon

Les pointeurs étiquetés Objective-C poussent cela à l'extrême. Les nombres entiers jusqu'à 56 bits et de nombreuses chaînes jusqu'à six caractères ne sont même pas alloués en tant qu'objets, mais toutes les informations sont regroupées dans le pointeur d'objet lui-même.
gnasher729

9

Graphique. En règle générale, une image raster (qui est l'épine dorsale de la plupart des graphiques informatiques de niveau consommateur) est peu coûteuse en CPU, mais coûteuse en mémoire pour travailler (ce qui est bien car la mémoire est bon marché mais le CPU est cher). Si cette image raster doit être répétée plusieurs fois dans le rendu d'une plus grande interface utilisateur (des icônes dans une application graphique Windows aux caractères d'une police dans un traitement de texte, aux textures sur les surfaces dans un jeu 3D), cela a beaucoup de sens pour chargez l'image en mémoire une fois et pointez-la simplement sur des objets très simples, peu coûteux à fabriquer et qui, eux-mêmes, ne prennent pas beaucoup de mémoire. Un sprite, qui est simplement un point dans l'espace graphique auquel une image doit être affichée, n'est qu'un point 3D et un pointeur de mémoire sur le premier pixel de l'image à utiliser. PEUT-ÊTRE qu'il inclut également les dimensions de la partie du fichier image sprite à utiliser, en termes graphiques ou de mémoire. Ces informations sont toutes très peu coûteuses à modifier, par exemple pour changer l'image ou l'emplacement du sprite, et cela peut être fait sans charger une nouvelle image à chaque fois, augmentant ainsi considérablement les performances du programme sous-jacent pour manipuler et afficher les parties appropriées du des images appropriées pour rendre une "scène" d'interface utilisateur complète.


3

Les Characterinstances de plage ASCII dans Smalltalk sont des masselottes.

Lorsque vous évaluez quelque chose comme Character space, Character class >> #value:exécute:

value: anInteger 
    "Answer the Character whose value is anInteger."

    anInteger > 255 ifTrue: [^self basicNew setValue: anInteger].
    ^ CharacterTable at: anInteger + 1.

La variable de classe CharacterTableest initialisée comme ceci:

initialize
    "Create the table of unique Characters, and DigitsValues."
    "Character initializeClassificationTable"

    CharacterTable ifNil: [
        "Initialize only once to ensure that byte characters are unique"
        CharacterTable := Array new: 256.
        1 to: 256 do: [:i | CharacterTable
            at: i
            put: (self basicNew setValue: i - 1)]].
    self initializeDigitValues

Ainsi, lorsque vous créez une chaîne, les plages ASCII Characterproviendront CharacterTableplutôt que d'être nouvellement créées à chaque fois.


3

Le but de l'utilisation du modèle flyweight est d'éviter l'initialisation inutile des objets et ainsi d'économiser de l'espace. Comme défini par GOF , un objet peut avoir deux états, l'état intrinsèque et l'état extrinsèque:

  • État intrinsèque: est stocké dans la masselotte; il se compose d'informations indépendantes du contexte des masselottes, ce qui les rend partageables.
  • État extrinsèque: dépend et varie selon le contexte de la masselotte et ne peut donc pas être partagé. Les objets clients sont responsables de la transmission de l'état extrinsèque à la masselotte lorsqu'elle en a besoin.

En supposant que nous voulons développer une application d'édition de texte simple où chaque colonne contient toutes les lignes du texte et la ligne peut contenir des caractères.

Le dilemme ici est de savoir comment concevoir la classe Character. L' char cintérieur de la classe Character doit être l'objet principal (état intrinsèque). Cependant, un caractère peut avoir une police et une taille (état extrinsèque); nous devons donc stocker son état extrinsèque sur la ligne (client) et y accéder en cas de besoin. À cet effet, deux listes qui stockent les polices et les tailles sont créées.

En suivant le modèle Flyweight, le personnage est désormais réutilisable et les objets sont référencés à partir d'une liste spécifique d'objets (le pool de poids volants) qui contient tous les symboles ASCII ( Characterobjets).

Voici ce que j'ai décrit visuellement:

entrez la description de l'image ici

Pour imprimer «bonjour», seuls 4 Characterobjets sont nécessaires, au lieu de 5. Une fois la police modifiée, aucun nouvel objet n'est requis; notez que cela ne serait pas possible si nous avions stocké l'état extrinsèque sur la classe Character, par exemple,

class Character
{
    char c;
    int Size;
    Font font;

    ....
}

L'application de ce modèle sur de grands ensembles de données entraînerait des optimisations importantes sur la complexité de la mémoire de l'application et la réutilisation des objets.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.