This article is part 2 of the Design Pattern series.
The flyweight pattern is a design pattern that is used to minimize resource usage when working with very large numbers of objects. When creating many thousands of identical objects, stateless flyweights can lower the memory used to a manageable level. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. For each of objects which use shared data only reference to shared object is saved.
When programs work with a large number of objects which have the same structure and some states of this objects don’t vary in time. When we use traditional approach and we create instances of this objects and fill state variables with values, the memory and storage requirements may unacceptably increase.
The flyweight design pattern often uses a variation on the factory method pattern for the generation of the shared objects. The factory receives a request for a flyweight instance. If a matching object is already in use, that particular object is returned. If not, a new flyweight is generated.
In the flyweight pattern, there is the concept of Intrinsic and Extrinsic state. Intrinsic states are things that are constant and are stored in the memory. Extrinsic states are things that are not constant and need to be calculated on the fly, and are therefore not stored in the memory.
Using the flyweight pattern, you can have any number of different instances in use simultaneously, (each one of which is used multiple times). The canonical example of the flyweight pattern is for a text editor, where you need an object instantiated for each and every character in the document. Instead of having one object in memory for each character in a 10,000 word document, you then only need 26 objects, (assuming document only uses lower case letters), one for the letter ‘a’, one for the letter ‘b’, etc., and they are reused, transiently, over and over again throughout the document, each time you need to perform some function or action requiring an ‘a’ object.
If the letter class was a static, or a singleton, that wouldn’t work. You’d have to have 26 different classes, one for each letter.
Also, the “part of the class that can vary” really means that some fields represent state that is different for every instance of the class. Whereas the part that is in common means that the values of those common fields are in common for all uses of the object matching those state values (all the ‘a’s for example), not for every instance of the class.
Again, using the text editor as an example. Every place in your code that you need to deal with a character that is an ‘a’, you would first, go to the data structure that stores your 26 instances of character objects, and fetch the ‘a’ instance, You would first modify/change the varying properties (the properties not tied to its nature as an ‘a’, but perhaps to its font size, position, color, etc.) to match the needs for this specific character ‘a’ in the document.
Then you would utilize the object to do whatever it is you need to do with it, and then return it to the storage structure for reuse the next time your code needs an ‘a’.
Below you can see the UML for the flyweight design pattern:
FlyweightFactory class: FlyweightFactory class is just an indexer that allows you to retrieve the flyweight object when given an index number, since you may have many flyweight objects in your application.
IFlyweight interface: IFlyweight interface defines the methods and the properties required for the flyweight objects. The GetExtrinsicState method gets the extrinsic states and the intrinsicState variable holds the intrinsic states.
ConcreteFlyweight class: ConcreteFlyweight class is the actual flyweight object. The intrinsicState variable stores the information that are constant, while the GetExtrinsicState method calculates the extrinsic states on the fly.
This article is part of the Design Pattern series. Articles in this series include:
- Mediator Design Pattern
- Flyweight Design Pattern