VOOZH about

URL: https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Flyweight

⇱ Flyweight - Wikibooks, open books for an open world


Jump to content
From Wikibooks, open books for an open world
👁 Image
Factory method
Computer Science Design Patterns
Flyweight
Interpreter 👁 Image

It is a mechanism by which you can avoid creating a large number of object instances to represent the entire system. To decide if some part of a program is a candidate for using Flyweights, consider whether it is possible to remove some data from the class and make it extrinsic.

Examples

👁 Image

A classic example usage of the flyweight pattern is the data structures for graphical representation of characters in a word processor. It might be desirable to have, for each character in a document, a glyph object containing its font outline, font metrics, and other formatting data, but this would amount to hundreds or thousands of bytes for each character. Instead, for every character there might be a reference to a flyweight glyph object shared by every instance of the same character in the document; only the position of each character (in the document and/or the page) would need to be stored internally. Another example is string interning.

👁 Image

In video games, it is usual that you have to display the same sprite (i.e. an image of an item of the game) several times. It would highly use the CPU and the memory if each sprite was a different object. So the sprite is created once and then is rendered at different locations in the screen. This problem can be solved using the flyweight pattern. The object that renders the sprite is a flyweight.

Cost

There are several implementations for this pattern. So it's up to you to find a cheap implementation. Only implement this pattern if you have or will have CPU or memory issues.

Creation

This pattern is quite easy to create.

Maintenance

This pattern is quite easy to maintain.

Removal

This pattern is quite easy to remove too.

Advises

  • Use pre-existing tools from the language like the sets in Java.

Implementations

Implementation in Java

The following programs illustrate the document example given above: the flyweights are called FontData in the Java example. The examples illustrate the flyweight pattern used to reduce memory by loading only the data necessary to perform some immediate task from a large Font object into a much smaller FontData (flyweight) object.

importjava.lang.ref.WeakReference;
importjava.util.WeakHashMap;
importjava.util.Collections;
importjava.util.EnumSet;
importjava.util.Set;
importjava.awt.Color;
publicfinalclass FontData{
enumFontEffect{
BOLD,ITALIC,SUPERSCRIPT,SUBSCRIPT,STRIKETHROUGH
}
/**
 * A weak hash map will drop unused references to FontData.
 * Values have to be wrapped in WeakReferences, 
 * because value objects in weak hash map are held by strong references.
 */
privatestaticfinalWeakHashMap<FontData,WeakReference<FontData>>FLY_WEIGHT_DATA=
newWeakHashMap<FontData,WeakReference<FontData>>();
privatefinalintpointSize;
privatefinalStringfontFace;
privatefinalColorcolor;
privatefinalSet<FontEffect>effects;
privateFontData(intpointSize,StringfontFace,Colorcolor,EnumSet<FontEffect>effects){
this.pointSize=pointSize;
this.fontFace=fontFace;
this.color=color;
this.effects=Collections.unmodifiableSet(effects);
}
publicstaticFontDatacreate(intpointSize,StringfontFace,Colorcolor,
FontEffect...effects){
EnumSet<FontEffect>effectsSet=EnumSet.noneOf(FontEffect.class);
for(FontEffectfontEffect:effects){
effectsSet.add(fontEffect);
}
// We are unconcerned with object creation cost, we are reducing overall memory consumption
FontDatadata=newFontData(pointSize,fontFace,color,effectsSet);
FontDataresult=null;
// Retrieve previously created instance with the given values if it (still) exists
WeakReference<FontData>ref=FLY_WEIGHT_DATA.get(data);
if(ref!=null){
result=ref.get();
}
// Store new font data instance if no matching instance exists
if(result==null){
FLY_WEIGHT_DATA.put(data,newWeakReference<FontData>(data));
result=data;
}
// return the single immutable copy with the given values
returnresult;
}
@Override
publicbooleanequals(Objectobj){
if(objinstanceofFontData){
if(obj==this){
returntrue;
}
FontDataother=(FontData)obj;
returnother.pointSize==pointSize&&other.fontFace.equals(fontFace)
&&other.color.equals(color)&&other.effects.equals(effects);
}
returnfalse;
}
@Override
publicinthashCode(){
return(pointSize*37+effects.hashCode()*13)*fontFace.hashCode();
}
// Getters for the font data, but no setters. FontData is immutable.
}
Implementation in Python
'''http://codesnipers.com/?q=python-flyweights'''

from__future__import print_function
importweakref

classCard(object):

 # comment __new__ and uncomment __init__ to see the difference

'''The object pool. Has builtin reference counting'''
 _CardPool = weakref.WeakValueDictionary()

'''If the object exists in the pool just return it (instead of creating a new one)'''
 def__new__(cls, value, suit):
 obj = Card._CardPool.get(value + suit, None)
 if not obj:
 obj = object.__new__(cls)
 Card._CardPool[value + suit] = obj
 obj.value, obj.suit = value, suit
 return obj

 # def __init__(self, value, suit):
 # self.value, self.suit = value, suit

 def__repr__(self):
 return "<Card: %s%s>" % (self.value, self.suit)

if __name__ == '__main__':
 c1 = Card('9', 'h')
 c2 = Card('9', 'h')
 print(c1, c2)
 print(c1 == c2)
 print(id(c1), id(c2))


👁 Clipboard

To do:
Add more illustrations.


👁 Image
Factory method
Computer Science Design Patterns
Flyweight
Interpreter 👁 Image



Ask it here: