Flyweight pattern

From Wikipedia, the free encyclopedia

Flyweight is a software design pattern. When many objects must be manipulated and these cannot afford to have extraneous data, flyweight is appropriate.

In the flyweight pattern, the data has no pointers to the data type methods, because these would consume too much space. Instead, the subroutines are called directly. In some cases, flyweight inheritance is performed by "shift-in" and "shift-out" data markers as a higher-level operation cycles through an array of flyweight data.

One classic example of a flyweight pattern are the characters stored in a word processor. Each character represents an object that has a font face, font size, and other formatting data. A large document with this data structure would bloat the memory footprint of the word processor. Moreover, since much of this data is repeated, there must be a way to reduce the footprint - the Flyweight pattern. Each of the character objects would contain a reference to a separate formatting object which contains the required properties. This greatly reduces the memory footprint by combining all of the like-formatted characters into simpler objects that reference a single formatting object.

There is also a version of this pattern for working with XML structures.

[edit] Examples

[edit] Java

The following Java program illustrates the example given above. It outputs:

CharFactory created only 4 objects for 5 characters!
Printing 'H' in 'Arial' at position 0:0.
Printing 'e' in 'Arial' at position 1:0.
Printing 'l' in 'Arial' at position 2:0.
Printing 'l' in 'Arial' at position 3:0.
Printing 'o' in 'Times' at position 4:0.
import java.util.*;

class GraphicChar {
   char c;
   String fontFace;
   public GraphicChar(char c, String fontFace) { this.c = c; this.fontFace = fontFace; }
   public static void printAtPosition(GraphicChar c, int x, int y)   {
       System.out.printf("Printing '%c' in '%s' at position %d:%d.\n", c.c, c.fontFace, x, y);
   }
}

class GraphicCharFactory {
   HashMap<String, GraphicChar> pool = new HashMap<String, GraphicChar>(); // the Flyweights

   public int getNum() { return pool.size(); }

   public GraphicChar get(Character c, String fontFace) {
       GraphicChar gc;
       String key = c.toString() + fontFace;
       if ((gc = pool.get(key)) == null) {
           gc = new GraphicChar(c, fontFace);
           pool.put(key, gc);
       }
       return gc;
   }
}

class FlyWeightExample {
   public static void main(String[] args) {
       GraphicCharFactory cf = new GraphicCharFactory();

       // Compose the text by storing the characters as objects.
       ArrayList<GraphicChar> text = new ArrayList<GraphicChar>();
       text.add( cf.get('H', "Arial") );    // 'H' and "Arial" are called intrinsic information
       text.add( cf.get('e', "Arial") );    // because it is stored in the object itself.
       text.add( cf.get('l', "Arial") );
       text.add( cf.get('l', "Arial") );
       text.add( cf.get('o', "Times") );

       // See how the Flyweight approach is beginning to save space:
       System.out.printf("CharFactory created only %d objects for %d characters.\n", cf.getNum(), text.size());

       int x=0, y=0;
       for (GraphicChar c : text) {        // Passing position as extrinsic information to the objects,
           GraphicChar.printAtPosition(c, x++, y);      // as a top-left 'A' is not different to a top-right one.
       }
   }
}

[edit] External links