Flyweight - shoonie/StudyingDesignPattern GitHub Wiki
Use sharing to support large numbers of fine-grained objects efficiently.
Flyweights may introduce run-time costs associated with transferring, finding, and/or computing extrinsic state especially if it was formerly stored as intrinsic state. However, such costs are offset by space savings, which increase as more flyweights are shared. Storage savings are a function of several factors.
- the reduction in the total number of instances that comes from sharing
- the amount of intrinsic state per object.
- whether extrinsic state is computed or state. The more flyweights are shared, the greater the storage savings.
- Removing extrinsic state.
- Managing shared objects.
// from https://advancedcppwithexamples.blogspot.com/2010/10/c-example-of-flyweight-design-pattern.html
#include<iostream>
#include<string>
#include<map>
using namespace std;
// The 'Flyweight' abstract class
class Character
{
public:
virtual void Display(int pointSize) = 0;
protected:
char symbol_;
int width_;
int height_;
int ascent_;
int descent_;
int pointSize_;
};
// A 'ConcreteFlyweight' class
class CharacterA : public Character
{
public:
CharacterA()
{
symbol_ = 'A';
width_ = 120;
height_ = 100;
ascent_ = 70;
descent_ = 0;
pointSize_ = 0; //initialise
}
void Display(int pointSize)
{
pointSize_ = pointSize;
cout<<symbol_<<" (pointsize "<<pointSize_<<" )"<<endl;
}
};
// A 'ConcreteFlyweight' class
class CharacterB : public Character
{
public:
CharacterB()
{
symbol_ = 'B';
width_ = 140;
height_ = 100;
ascent_ = 72;
descent_ = 0;
pointSize_ = 0; //initialise
}
void Display(int pointSize)
{
pointSize_ = pointSize;
cout<<symbol_<<" (pointsize "<<pointSize_<<" )"<<endl;
}
};
//C, D, E,...
// A 'ConcreteFlyweight' class
class CharacterZ : public Character
{
public:
CharacterZ()
{
symbol_ = 'Z';
width_ = 100;
height_ = 100;
ascent_ = 68;
descent_ = 0;
pointSize_ = 0; //initialise
}
void Display(int pointSize)
{
pointSize_ = pointSize;
cout<<symbol_<<" (pointsize "<<pointSize_<<" )"<<endl;
}
};
// The 'FlyweightFactory' class
class CharacterFactory
{
public:
virtual ~CharacterFactory()
{
while(!characters_.empty())
{
map<char, Character*>::iterator it = characters_.begin();
delete it->second;
characters_.erase(it);
}
}
Character* GetCharacter(char key)
{
Character* character = NULL;
if(characters_.find(key) != characters_.end())
{
character = characters_[key];
}
else
{
switch(key)
{
case 'A':
character = new CharacterA();
break;
case 'B':
character = new CharacterB();
break;
//...
case 'Z':
character = new CharacterZ();
break;
default:
cout<<"Not Implemented"<<endl;
throw("Not Implemented");
}
characters_[key] = character;
}
return character;
}
private:
map<char, Character*> characters_;
};
//The Main method
int main()
{
string document = "AAZZBBZB";
const char* chars = document.c_str();
CharacterFactory* factory = new CharacterFactory;
// extrinsic state
int pointSize = 10;
// For each character use a flyweight object
for(size_t i = 0; i < document.length(); i++)
{
pointSize++;
Character* character = factory->GetCharacter(chars[i]);
character->Display(pointSize);
}
//Clean memory
delete factory;
return 0;
}
// also many examples of making lots of trees in the game.
// check http://gameprogrammingpatterns.com/flyweight.html