I am using the Flyweight
pattern to cache and reuse objects of the different classes. For example, I have a Shape
interface class and multiple types of Shapes implementing the methods from the interface. I also have a factory class that has the cache of object types and object as key value.
As you can see, there is a Draw
method implemented in each of the derived classes but the problem is for each of my classes I want to have draw methods with different signatures.
eg for Rectangle, draw method takes length and breadth and for circle, only one argument radius is needed.
Using the same Shape interface, is there any way or design pattern to implement different Draw signatures in the derived classes.
Expected function definition
void Rectangle::Draw(int length, int breadth, int color) void Circle::Draw(int radius, int color)
Current implementation
class Shape { public: virtual void Draw() const = 0; }; class Circle : public Shape { public: Circle() { sleep(5); std::cout<<"Creation of circle object took 5s"<<std::endl; } void Draw() const override { std::cout<<"Drawing circle of radius"<<std::endl; } }; class Rectangle : public Shape { public: Rectangle() { sleep(7); std::cout<<"Creation of Rectangle object took 7s"<<std::endl; } void Draw() const override { std::cout<<"Drawing Rectangle of length and breadth"<<std::endl; } }; enum class ShapeTypes { Circles = 1, Rectangles }; class Factory { std::map <ShapeTypes, Shape*> shapeObjectCache; public: Shape* GetObject(ShapeTypes shapeType) { if(shapeObjectCache.find(shapeType) != shapeObjectCache.end()) { std::cout<<"Object of type " << static_cast<int>(shapeType) << " found in cache: "<<std::endl; return shapeObjectCache[shapeType]; } switch(shapeType) { case ShapeTypes::Circles: shapeObjectCache.insert({ ShapeTypes::Circles, new Circle() }); break; case ShapeTypes::Rectangles: shapeObjectCache.insert({ ShapeTypes::Rectangles, new Rectangle() }); break; } return shapeObjectCache[shapeType]; } ~Factory() { for (auto& entry : shapeObjectCache) { delete entry.second; } } }; int main() { Factory factory; Shape *circle1 = factory.GetObject(ShapeTypes::Circles); circle1->Draw(); Shape *rectangle1 = factory.GetObject(ShapeTypes::Rectangles); rectangle1->Draw(); Shape *circle2 = factory.GetObject(ShapeTypes::Circles); circle2->Draw(); return 0; }
Some suggested: why not create them as class member variable and pass the value in the constructor?
The problem with this approach is I am storing the objects in cache and since they will have some initial state set, I won't be able to reuse those objects and call the draw method and hence this will not be a flyweight pattern anymore.
Draw
methods which can pass different values, depending on the type of shape. But this caller needs to get that different data from somewhere - and where is this? Some list ofShapeData
objects? These objects will finally need as much memory as the data requires, which is exactly the same amount as if you would store the data directly as members insider the Shape objects. So your whole "Flyweight" approach stops making any sense. Please clarify.