Flyweight

Gamma et al. 95

Problème

  • On doit instancier un grand nombre de petits objets

  • Trop gourmand au niveau de la mémoire

Exemples
  • Du texte contenant un grand nombre de caractères

  • Un jeu massivement multi-joueurs (les objets graphiques)

  • L’ADN

Objectif

Partager efficacement un grand nombre de petits objets

  1. Fonctionnement :

    • Certaines données sont extraites du l’objet pour en minimiser le nombre d’instanciation

Exemple : l’ADN
  • Seuls 4 bases azotées créées (G, A, T, C)

  • Leur position est stockée en dehors (dans l’ADN)

  • Sinon explosion du nombre d’instances de bases azotées

Structure

flyweight structure
  • FabriquePoidsMouche: créer des objets que quand nécessaire (sinon retourne l’objet déjà existant)

  • L’utilisation du patron dans le code client passe par la fabrique pour obtenir des instances

Structure (Cont.)

flyweight structure
  • PoidsMoucheConcret ne contient pas certaines données

  • Elles lui seront passées en paramètres (étatExtrinsèque)

  • PoidsMoucheConcretNonPartagé : cas spécial de poids-mouche qui n’externalise pas ses données

Exemple: Integer.java

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

See: OpenJDK

Exemple

flyweight example
  • Exemple : un texte se compose de caractères

  • Externalisation de la position/police des caractères

  • 1 seul caractère pour 1 valeur (a, b, c, etc.)

Exemple en Java

Fabrique Caractères
public final class FabriqueCaractere {
  public static FabriqueCaractere INSTANCE = new FabriqueCaractere();

  private Map<Integer, Caractere> mapCaracteres;

  private FabriqueCaractere() {
    mapCaracteres = new IdentityHashMap<Integer, Caractere>();
  }


  public Caractere ObtenirCaractere(char valeur) {
    Caractere car = mapCaracteres.get(valeur);

    if(car==null) {
      car = new Caractere(valeur);
      mapCaracteres.put((int)valeur, car);
    }
    return car;
  }
}

Exemple en Java (Cont.)

Texte
public class Texte {
  protected List<Caractere> caracts;

  public Texte() {
    caracts = new ArrayList<Caractere>();
  }

  public void afficher(Graphics2D g) {
    //...
  }

  public void ajouterCaractere(char valeur) {
    caracts.add(FabriqueCaractere.INSTANCE.ObtenirCaractere(valeur));
  }
}

Exemple en Java (Cont.)

Caractère
public class Caractere {
  protected char valeur;
  //..

  public Caractere(char valeur) {
    this.valeur = valeur;
  }

  public void afficher(Graphics2D g, Point position) {
    //...
  }
}