Flyweight Design Pattern Explained With Simple Example: Structural Design Pattern Category

The flyweight design pattern allows to greatly reduce memory footprint of any product by dividing an object into basically two parts. If multiple objects have some internal part as common then all these objects can share these memory to reduce memory consumption. The other part which varies from object to object will still be part of final object. The common part of various object is stored and shared via a “Flyweight” object. For Design patterns basic explanation see (Design Patterns Simplified Version).

Generic model class diagram of Decorator design pattern is as shown in image.

 

flyweight_design_pattern

In this design pattern all kind of shared Flyweight objects were created and then final product object uses one version of flyweight object based in its need which usually costs some performance. Hence, this design pattern is widely used where memory is a bigger issue than performance and also number of flyweight objects creation is kept under check to reduce the cost in finding correct shared object for any final product object.

Flyweight Design Pattern Code Example:

Let’s take a very basic example of Aeroplane industry scenario in which each aeroplane information is stored in form of class objects. Since, each aeroplane will have some common state like Type of aircraft, seating capacity, speed etc, these common information can be stored at one place in flyweight objects which will be shared by all same kind of objects. Other than these information, every aircraft will have Serial number and Manufacturing Date information which are unique per aircraft. Hence, these information will be saved directly in final object. Class diagram for the solution of this problem is as shown in image.

flyweight_pattern_example

Let’s have a look on the class definition for all Flyweight objects definition.

/* Flyweight Abstract Class */
class Model
{
private:
	string m_name;
	int m_capacity;
	int m_speed;

public:
	virtual void showDetails()
	{
		cout<<"Name : "<<m_name<<", Capacity : "<<m_capacity<<", Speed: "<<m_speed<<" knots"<<endl;
	}
	Model(string name, int capacity, int speed)
	{
		m_name = name;
		m_capacity = capacity;
		m_speed = speed;
	}
	Model(){};
};

/* Flyweight Concrete Class */
class Airbus380: public Model
{
public:
	Airbus380():Model("Airbus380", 200, 800) {}
};

/* Flyweight Concrete Class */
class Boeing787: public Model
{
public:
	Boeing787():Model("Boeing787", 600, 1000) {}
};

/* Flyweight Concrete Class */
class Boeing797: public Model
{
public:
	Boeing797():Model("Boeing797", 1200, 1500) {}
};

Now, Let’s have a look on the Flyweight Factory class which will keep one shared object of all above defined flyweight objects.

/* Flyweight Factory Class */
class FlyweightFactory
{
private:
	static Airbus380* s_airbus380;
	static Boeing787* s_boeing787;
	static Boeing797* s_boeing797;

public:
	static Model* getModel(int type)
	{
		switch(type)
		{
		case 380:
			if(!s_airbus380)
			{
				s_airbus380 = new Airbus380();
			}
			return s_airbus380;

		case 787:
			if(!s_boeing787)
			{
				s_boeing787 = new Boeing787();
			}
			return s_boeing787;
			
		case 797:
			if(!s_boeing797)
			{
				s_boeing797 = new Boeing797();
			}
			return s_boeing797;

		default:
			cout<<"Unknown aeroplane type"<<endl;
			return NULL;
		}
	}
};

Airbus380* FlyweightFactory::s_airbus380;
Boeing787* FlyweightFactory::s_boeing787;
Boeing797* FlyweightFactory::s_boeing797;

Now, Let’s look at the final product definition which will share the common information via shared object which it will get from Flyweight factory whereas unique information will be stored in this class only.

/* Product Class */
class Aeroplane: public Model
{
private:
	Model* m_model;
	string m_mfgDate;
	int m_id;

public:
	Aeroplane(Model* model, string date, int id)
	{
		m_model = model;
		m_mfgDate = date;
		m_id = id;
	}

	virtual void showDetails()
	{
		m_model->showDetails();
		cout<<"MfgDate : "<<m_mfgDate<<", Serial No: "<<m_id<<endl;
	}
};

Let’s see now how to use the above described classes to build the final product. Below code is sample “main” function code.

int main()
{
	Aeroplane first = Aeroplane(FlyweightFactory::getModel(787), "10th Feb 1987", 100213);
	Aeroplane second = Aeroplane(FlyweightFactory::getModel(797), "1th Feb 1987", 100214);
	Aeroplane third = Aeroplane(FlyweightFactory::getModel(787), "20th Jan 1987", 100215);
	Aeroplane forth = Aeroplane(FlyweightFactory::getModel(380), "10th mar 1987", 200216);

	first.showDetails();
	second.showDetails();
	third.showDetails();
	forth.showDetails();
}

Output of the above given example:

Name : Boeing787, Capacity : 600, Speed: 1000 knots
MfgDate : 10th Feb 1987, Serial No: 100213
Name : Boeing797, Capacity : 1200, Speed: 1500 knots
MfgDate : 1th Feb 1987, Serial No: 100214
Name : Boeing787, Capacity : 600, Speed: 1000 knots
MfgDate : 20th Jan 1987, Serial No: 100215
Name : Airbus380, Capacity : 200, Speed: 800 knots
MfgDate : 10th mar 1987, Serial No: 200216

Leave a Reply

Your email address will not be published. Required fields are marked *