This set of slide decks was prepared by me and Amit for use in demonstrating Flyweight Pattern in our Design Pattern class at SU. You can download the code examples (C++ visual studio projects) from here: http://sdrv.ms/TsvEQl
4. Introduction
Designing objects down to the lowest levels of system granularity
provides optimal flexibility, but can be unacceptably expensive in
terms of performance and memory usage.
The Flyweight Pattern is a pattern for greatly reducing memory
requirements.
The flyweight pattern applies to a program using a huge number of
objects that have part of their internal state in common where the
other part of state can vary.
The idea behind flyweight pattern is shareable objects.
5. Structure of the Flyweight
It can be confusing at first to understand how the flyweight
pattern works. Let’s first take a high-level look at the structure.
SUID
Each object is divided into two pieces:
First Name
student
-- the state-independent (intrinsic) part
-- and the state-dependent (extrinsic) part
Last Name
Intrinsic state is stored (shared) in the Flyweight object. Department
Extrinsic state is stored or computed by client objects, and University
Name
passed to the Flyweight when its operations are invoked.
7. Word Processor
A classic example usage of the flyweight pattern is the data structures
for graphical representation of characters in a word processor.
The term flyweight pattern was first coined and extensively explored
by Paul Calder and Mark Linton in 1990 to efficiently handle glyph
information in a WYSIWYG document editor.
For each character in a document, we can create a glyph object
containing information such as the font family, size, weight of each
character and other formatting data.
The problem here is that a lengthy document might contain tens of
thousands of characters and corresponding objects - quite a memory
killer !!!
8. The Flyweight pattern addresses the problem by creating a new object
to store such information, which is shared by all characters with the
same formatting.
The intrinsic state here could be the shared information such as font-
family, font-size, font weight and so one.
The extrinsic state would be the information that distinguishes each
physical character such as row information or the x-y co-ordinate of the
character.
So, if I had a ten-thousand word document, with 800 characters in Bold
Times-New-Roman size-14pt, these 800 characters would contain a
reference to a flyweight object that stores their common formatting
information.
The key here is that you only store the information once, so memory
consumption is greatly reduced.
9. Aircraft Example
Lets suppose we have to model some complex aircrafts such
as Airbus 380 and Boeing 797
10. Aircraft Flyweight Object
Wingspan Wingspan
Speed Speed
Capacity Capacity
Serial
Number
Date
bought
11. public class Boeing797
public class Airbus380 ::public IModel
public IModel
{
private:
private:
std::string name;
std::string name;
public class IModel std::string wingspan;
std::string wingspan;
int capacity;
int capacity;
{ std::string speed;
std::string speed;
std::string range;
private: std::string range;
public:
std::string name; public: Airbus380()
Boeing797 ()
{
{
std::string wingspan; name = "AirBus380";
name = "Boeing797";
wingspan = "80.8 meters";
int capacity; wingspan = "79.8 meters";
capacity = 1000;
capacity = 555;
std::string speed; speed = "1046 km per hr";
speed = "912 km per hr";
range = "14400 km";
range = "10370 km";
std::string range; }
}
void print ()
void print ()
{
{
public: virtual void print () = 0; cout << "Name : " << name << "n";
cout << "Name : " << name << "n";
cout << "Wingspan : " << wingspan << "n";
}; cout << "Wingspan : " << wingspan << "n";
cout << "Capacity : " << capacity << "n";
cout << "Capacity : " << capacity << "n";
cout << "Speed :: "" << speed << "n";
cout << "Speed << speed << "n";
}}
};
};
12. public class FlyweightFactory { public class Aircraft {
private: private:
IModel *_type;
static Airbus380 *a;
int _serialNo;
static Boeing797 *b; std::string _dateBought;
public:
public:
Aircraft (IModel *type, int serialNo,
static IModel * GetObj (int typeNo) { std::string dateBought)
if (typeNo == 380) { {
_type = type ;
if(a == NULL)
_serialNo = serialNo ;
a = new Airbus380(); _dateBought = dateBought ;
return a; }
}
void print()
else { //if typeNo is 797 {
if(b == NULL) _type->print();
cout << "Serial No : " << _serialNo <<
b = new Boeing797();
"n";
return b; cout << "Date Bought : " <<
} _dateBought << "n";
cout << endl ;
}
}
}; };
13. // Global Static object pointer
Airbus380 * FlyweightFactory::a;
Boeing797 * FlyweightFactory::b;
// Client:
void main()
{
Aircraft one = Aircraft( FlyweightFactory::GetObj(380) , 1001,"9th feb 2011");
Aircraft two = Aircraft( FlyweightFactory::GetObj(380) , 1002, "11th sept 2011");
Aircraft three = Aircraft( FlyweightFactory::GetObj(797) , 1003, "12th oct 2011");
Aircraft four = Aircraft( FlyweightFactory::GetObj(797) , 1004, "13th dec 2011");
one.print();
two.print();
three.print();
four.print();
}
19. Summary
• “Flyweights” Lose Equality, Gain Identity
• Same Instance used Many Places
• “Flyweights” Must Separate Intrinsic/Extrinsic
• “Flyweights” Save Space
• More “Flyweights” Shared Yields More Savings
• More Intrinsic State Yields More Savings
• “Flyweights” Are Found, Not Instantiated
• Slight Shift in Terminology
• “Flyweights” May Introduce CPU Costs
• Finding “Flyweights” (Large Pool Increases)