Bird
Raised Fist0
LLDsystem_design~7 mins

Flyweight pattern in LLD - System Design Guide

Choose your learning style10 modes available
Problem Statement
When a system creates many objects with identical or similar data, memory usage grows rapidly, causing slow performance and high resource consumption. This often happens in graphical applications or text editors where many repeated elements exist, leading to inefficient memory use.
Solution
The Flyweight pattern reduces memory use by sharing common parts of objects instead of storing them separately. It separates intrinsic (shared) state from extrinsic (unique) state, storing shared data once and passing unique data externally when needed.
Architecture
Client
(requests) ─┼───────▶
→(creates/shares)
↓

This diagram shows how the client requests flyweight objects from the factory, which creates or reuses shared objects containing intrinsic state.

Trade-offs
✓ Pros
→
Significantly reduces memory usage by sharing common data among many objects.
→
Improves performance by lowering object creation overhead.
→
Enables handling large numbers of fine-grained objects efficiently.
✗ Cons
→
Increases complexity by separating intrinsic and extrinsic state.
→
Requires careful management of extrinsic state passed externally.
→
Not suitable if objects have mostly unique data with little shared state.
Use when your system creates millions of similar objects with large shared data, such as text editors rendering characters or graphical applications with repeated shapes.
Avoid when objects have mostly unique data or when the overhead of managing extrinsic state outweighs memory savings, typically under 10,000 objects.
Real World Examples
Microsoft
Microsoft Word uses flyweight to efficiently render millions of characters by sharing font and style data among characters.
Google
Google Maps uses flyweight to share map tile data among many map views, reducing memory use.
Adobe
Adobe Illustrator shares graphical object data to handle complex vector graphics with many repeated elements.
Code Example
The before code creates a new Tree object with full data for each instance, wasting memory. The after code separates shared data (TreeType) and unique data (coordinates), reusing TreeType objects to save memory.
LLD
### Before Flyweight (naive, no sharing)
class Tree:
    def __init__(self, x, y, type_):
        self.x = x
        self.y = y
        self.type = type_  # large data like tree type info

# Creating many trees with repeated type data
forest = [Tree(i, j, 'Oak') for i in range(1000) for j in range(1000)]


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

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)
        return cls._tree_types[key]

class Tree:
    def __init__(self, x, y, tree_type):
        self.x = x
        self.y = y
        self.tree_type = tree_type  # shared intrinsic state

# Creating many trees sharing TreeType objects
forest = []
for i in range(1000):
    for j in range(1000):
        tree_type = TreeFactory.get_tree_type('Oak', 'Green', 'Rough')
        forest.append(Tree(i, j, tree_type))
OutputSuccess
Alternatives
Prototype pattern
Creates new objects by cloning existing ones rather than sharing intrinsic state.
Use when: Choose when you need many similar but independent objects with slight variations.
Object Pool pattern
Reuses a fixed set of objects instead of sharing intrinsic data, focusing on object lifecycle management.
Use when: Choose when object creation is expensive and you want to reuse whole objects rather than parts.
Summary
Flyweight pattern reduces memory use by sharing common parts of many similar objects.
It separates shared intrinsic state from unique extrinsic state passed externally.
This pattern is ideal for systems with millions of fine-grained objects having repeated data.

Practice

(1/5)
1. What is the main purpose of the Flyweight pattern in system design?
easy
A. To encrypt data for security
B. To save memory by sharing common parts of objects
C. To improve network communication speed
D. To create new objects for every request

Solution

  1. Step 1: Understand the Flyweight pattern goal

    The Flyweight pattern focuses on reducing memory usage by sharing common data among many objects.
  2. Step 2: Compare options with the pattern goal

    Only To save memory by sharing common parts of objects matches the purpose of saving memory by sharing parts of objects.
  3. Final Answer:

    To save memory by sharing common parts of objects -> Option B
  4. Quick Check:

    Flyweight = Memory sharing [OK]
Hint: Flyweight shares data to save memory, not speed or security [OK]
Common Mistakes:
  • Confusing Flyweight with caching or encryption
  • Thinking Flyweight creates new objects each time
  • Mixing Flyweight with network optimization
2. Which of the following is the correct way to separate intrinsic and extrinsic state in a Flyweight object?
easy
A. Store shared data inside the Flyweight and pass unique data externally
B. Do not separate data; treat all data as shared
C. Keep all data inside the Flyweight object
D. Store unique data inside the Flyweight and shared data outside

Solution

  1. Step 1: Recall Flyweight data separation

    Flyweight stores intrinsic (shared) data internally and receives extrinsic (unique) data externally.
  2. Step 2: Match options with this rule

    Store shared data inside the Flyweight and pass unique data externally correctly states shared data inside Flyweight and unique data passed externally.
  3. Final Answer:

    Store shared data inside the Flyweight and pass unique data externally -> Option A
  4. Quick Check:

    Intrinsic inside, extrinsic outside [OK]
Hint: Flyweight holds shared data; unique data comes from outside [OK]
Common Mistakes:
  • Putting unique data inside Flyweight causing duplication
  • Not separating data leading to memory waste
  • Confusing intrinsic and extrinsic states
3. Consider this simplified Flyweight usage in code:
class TreeType:
    def __init__(self, name, color):
        self.name = name
        self.color = color

class TreeFactory:
    _tree_types = {}

    @classmethod
    def get_tree_type(cls, name, color):
        key = (name, color)
        if key not in cls._tree_types:
            cls._tree_types[key] = TreeType(name, color)
        return cls._tree_types[key]

# Usage
factory = TreeFactory()
t1 = factory.get_tree_type('Oak', 'Green')
t2 = factory.get_tree_type('Oak', 'Green')
t3 = factory.get_tree_type('Pine', 'Green')
print(t1 is t2, t1 is t3)

What will be the output?
medium
A. True False
B. False True
C. True True
D. False False

Solution

  1. Step 1: Understand object sharing in factory

    The factory returns the same TreeType object for identical (name, color) keys, so t1 and t2 share the same object.
  2. Step 2: Compare object identities

    t1 is t2 will be True because they share the same instance; t1 is t3 will be False because 'Pine' differs from 'Oak'.
  3. Final Answer:

    True False -> Option A
  4. Quick Check:

    Shared keys = same object [OK]
Hint: Same key returns same object, different key returns new object [OK]
Common Mistakes:
  • Assuming all objects are different
  • Ignoring the factory cache
  • Confusing identity (is) with equality (==)
4. In this Flyweight implementation snippet, what is the main error?
class Flyweight:
    def __init__(self, shared_state):
        self.shared_state = shared_state

class FlyweightFactory:
    def __init__(self):
        self._flyweights = {}

    def get_flyweight(self, shared_state):
        if shared_state not in self._flyweights:
            self._flyweights[shared_state] = Flyweight(shared_state)
        return self._flyweights[shared_state]
medium
A. Creating new Flyweight every time
B. Not storing unique data inside Flyweight
C. Using mutable type as dictionary key without hashing
D. Missing constructor in Flyweight class

Solution

  1. Step 1: Identify dictionary key usage

    The code uses shared_state as a dictionary key, but if shared_state is a mutable type like a list or dict, it cannot be used as a key.
  2. Step 2: Understand dictionary key requirements

    Dictionary keys must be immutable and hashable; using mutable types causes runtime errors.
  3. Final Answer:

    Using mutable type as dictionary key without hashing -> Option C
  4. Quick Check:

    Dict keys must be immutable [OK]
Hint: Dict keys must be immutable; mutable keys cause errors [OK]
Common Mistakes:
  • Ignoring type of shared_state as dict key
  • Assuming Flyweight always stores unique data
  • Overlooking constructor presence
5. You are designing a text editor that displays millions of characters. Each character has a font style and color (shared), and a position (unique). How would you apply the Flyweight pattern here to optimize memory?
hard
A. Store position inside Flyweight and font/color externally
B. Store all data inside Flyweight objects without separation
C. Create a new object for every character without sharing
D. Create a Flyweight object for each unique character with its font and color, pass position externally

Solution

  1. Step 1: Identify intrinsic and extrinsic data

    Font style and color are shared (intrinsic), position is unique (extrinsic) for each character.
  2. Step 2: Apply Flyweight pattern correctly

    Create Flyweight objects for shared font and color, pass position externally when rendering characters.
  3. Final Answer:

    Create a Flyweight object for each unique character with its font and color, pass position externally -> Option D
  4. Quick Check:

    Shared data in Flyweight, unique data outside [OK]
Hint: Flyweight holds shared style; position passed externally [OK]
Common Mistakes:
  • Putting position inside Flyweight causing many objects
  • Not sharing font and color data
  • Ignoring separation of intrinsic and extrinsic data
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard