Flyweight Pattern

The Flyweight is a structural design pattern that minimizes memory usage by sharing common state (intrinsic) among similar objects, while keeping unique state (extrinsic) separate. It enables efficient handling of large numbers of lightweight objects by reusing immutable shared components, ideal for resource-constrained systems.

Key Principles

Structure

Python Example: Tree Rendering System

import copy

# Flyweight Interface (shared intrinsic state)
class TreeType:
    def __init__(self, name, color, texture):
        self.name = name
        self.color = color
        self.texture = texture

    def draw(self, canvas, x, y):  # Extrinsic state as params
        print(f"Drawing {self.name} at ({x}, {y}) with color {self.color} and texture {self.texture}")

# Flyweight Factory (manages pool)
class TreeFactory:
    _tree_types = {}

    @classmethod
    def get_tree_type(cls, name, color, texture):
        key = (name, color, texture)
        if key not in cls._tree_types:
            cls._tree_types[key] = TreeType(name, color, texture)
            print(f"Created new TreeType: {name}")
        return cls._tree_types[key]

# Context (holds extrinsic state + flyweight ref)
class Tree:
    def __init__(self, x, y, tree_type):
        self.x = x
        self.y = y
        self.tree_type = tree_type

    def draw(self, canvas):
        self.tree_type.draw(canvas, self.x, self.y)

# Client
class Forest:
    def __init__(self):
        self.trees = []

    def plant_tree(self, x, y, name, color, texture):
        tree_type = TreeFactory.get_tree_type(name, color, texture)  # Reuse if exists
        tree = Tree(x, y, tree_type)
        self.trees.append(tree)

    def draw(self, canvas):
        for tree in self.trees:
            tree.draw(canvas)

# Usage
if __name__ == "__main__":
    forest = Forest()
    forest.plant_tree(10, 20, "Oak", "Green", "Bark")  # Creates new
    forest.plant_tree(30, 40, "Oak", "Green", "Bark")  # Reuses
    forest.plant_tree(50, 60, "Pine", "Dark Green", "Needles")  # Creates new

    forest.draw(None)

Output:

Created new TreeType: Oak
Drawing Oak at (10, 20) with color Green and texture Bark
Drawing Oak at (30, 40) with color Green and texture Bark
Created new TreeType: Pine
Drawing Pine at (50, 60) with color Dark Green and texture Needles

When to Use Flyweight

Summary: Flyweight shares immutable common state across objects to save memory, using a factory for reuse, while extrinsic state is managed externally.