What if you could draw thousands of trees without your app crashing or slowing down?
Why Flyweight pattern in LLD? - Purpose & Use Cases
Imagine you are building a drawing app that needs to display thousands of similar shapes, like trees in a forest. If you create a new object for each tree, your app will use a lot of memory and slow down.
Creating separate objects for every similar item wastes memory and processing power. It becomes hard to manage and slows the system, especially when many objects share the same data.
The Flyweight pattern lets you share common parts of objects to save memory. Instead of making a full object for each item, you reuse shared data and only store unique details separately.
class Tree { constructor(type, color, x, y) { this.type = type; this.color = color; this.x = x; this.y = y; } } // Create 1000 trees, each with full data
class TreeType { constructor(type, color) { this.type = type; this.color = color; } } class Tree { constructor(treeType, x, y) { this.treeType = treeType; this.x = x; this.y = y; } } // Share TreeType objects among many trees
It enables building large systems with many similar objects efficiently, saving memory and improving performance.
Video games use the Flyweight pattern to render many identical characters or objects without slowing down the game.
Manual object creation wastes memory when many objects share data.
Flyweight shares common data to reduce memory use.
This pattern improves performance in systems with many similar objects.
Practice
Flyweight pattern in system design?Solution
Step 1: Understand the Flyweight pattern goal
The Flyweight pattern focuses on reducing memory usage by sharing common data among many objects.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.Final Answer:
To save memory by sharing common parts of objects -> Option BQuick Check:
Flyweight = Memory sharing [OK]
- Confusing Flyweight with caching or encryption
- Thinking Flyweight creates new objects each time
- Mixing Flyweight with network optimization
Solution
Step 1: Recall Flyweight data separation
Flyweight stores intrinsic (shared) data internally and receives extrinsic (unique) data externally.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.Final Answer:
Store shared data inside the Flyweight and pass unique data externally -> Option AQuick Check:
Intrinsic inside, extrinsic outside [OK]
- Putting unique data inside Flyweight causing duplication
- Not separating data leading to memory waste
- Confusing intrinsic and extrinsic states
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?
Solution
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.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'.Final Answer:
True False -> Option AQuick Check:
Shared keys = same object [OK]
- Assuming all objects are different
- Ignoring the factory cache
- Confusing identity (is) with equality (==)
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]Solution
Step 1: Identify dictionary key usage
The code usesshared_stateas a dictionary key, but ifshared_stateis a mutable type like a list or dict, it cannot be used as a key.Step 2: Understand dictionary key requirements
Dictionary keys must be immutable and hashable; using mutable types causes runtime errors.Final Answer:
Using mutable type as dictionary key without hashing -> Option CQuick Check:
Dict keys must be immutable [OK]
- Ignoring type of shared_state as dict key
- Assuming Flyweight always stores unique data
- Overlooking constructor presence
Solution
Step 1: Identify intrinsic and extrinsic data
Font style and color are shared (intrinsic), position is unique (extrinsic) for each character.Step 2: Apply Flyweight pattern correctly
Create Flyweight objects for shared font and color, pass position externally when rendering characters.Final Answer:
Create a Flyweight object for each unique character with its font and color, pass position externally -> Option DQuick Check:
Shared data in Flyweight, unique data outside [OK]
- Putting position inside Flyweight causing many objects
- Not sharing font and color data
- Ignoring separation of intrinsic and extrinsic data
Ready to prove it?
Pass the test and this pattern moves unknown
