The Flyweight design pattern is a structural design pattern that focuses on optimizing memory usage by sharing data between multiple objects. It is useful when you need to create a large number of similar objects that share common properties.
The main idea behind the Flyweight pattern is to separate the intrinsic (shared) and extrinsic (unique) parts of an object. The intrinsic part is immutable and can be shared among multiple objects, while the extrinsic part varies and is stored externally.
class Character:
def __init__(self, char):
self.char = char
def display(self, font_size):
print(f"Character: {self.char}, Font Size: {font_size}")
class CharacterFactory:
def __init__(self):
self.characters = {}
def get_character(self, char):
if char not in self.characters:
self.characters[char] = Character(char)
return self.characters[char]
# Client code
if __name__ == "__main__":
character_factory = CharacterFactory()
# Display characters using Flyweight pattern
text = "Hello, World!"
font_size = 12
for char in text:
character = character_factory.get_character(char)
character.display(font_size)
While it is common to see the Flyweight pattern implemented together with the Factory pattern, it is not a strict requirement for Flyweight to always use a factory pattern. The primary goal of the Flyweight pattern is to share common, immutable parts of objects to conserve memory.
It is possible to implement Flyweight without a factory, especially in simpler scenarios where the creation and management of flyweight objects can be handled directly within the client code.
A more complex example of the Flyweight pattern where the flyweight object receives an object and performs an operation that involves another complex object.
class Car:
def __init__(self, make, model, color):
self.make = make
self.model = model
self.color = color
def display_details(self, owner, extra_object):
print(f"Car: {self.make} {self.model} ({self.color}), Owned by: {owner}, Extra Object: {extra_object}")
class CarFlyweight:
def __init__(self, car):
self.car = car
def display_details(self, owner, extra_object):
self.car.display_details(owner, extra_object)
class CarFactory:
def __init__(self):
self.flyweights = {}
def get_flyweight(self, make, model, color):
key = (make, model, color)
if key not in self.flyweights:
car = Car(make, model, color)
self.flyweights[key] = CarFlyweight(car)
return self.flyweights[key]
# Client code
if __name__ == "__main__":
car_factory = CarFactory()
# Create flyweight objects with shared car state
flyweight1 = car_factory.get_flyweight("Toyota", "Camry", "Blue")
flyweight2 = car_factory.get_flyweight("Toyota", "Camry", "Blue")
# Use the flyweight objects with additional objects
owner1 = "John"
extra_object1 = "Object A"
flyweight1.display_details(owner1, extra_object1)
owner2 = "Alice"
extra_object2 = "Object B"
flyweight2.display_details(owner2, extra_object2)