Middle+
What is the Flyweight design pattern?
sobes.tech AI
Answer from AI
The Flyweight is a structural design pattern that allows saving memory by sharing state between multiple objects. It is used when an application has many similar objects, and most of them share the same state.
The pattern divides the object's state into two parts:
- Intrinsic State: The state shared by all objects and independent of their context. It is stored inside the Flyweight and shared among many clients.
- Extrinsic State: The state dependent on the context in which the object is used. It is passed to the Flyweight's methods by the client as needed.
Main components of the pattern:
- Flyweight: An interface or abstract class declaring methods that accept external state as a parameter.
- ConcreteFlyweight: A class implementing the Flyweight interface and storing the intrinsic state.
- FlyweightFactory: A class managing the creation and caching of ConcreteFlyweight objects. It checks if a Flyweight with the given intrinsic state already exists and returns it, or creates a new one.
- Client: An object that uses Flyweights, storing external state and invoking Flyweight methods, passing this state.
Example of use: a text editor. Characters (letters, digits) can be Flyweights. The internal state of a character is the character itself (e.g., 'A'). The external state includes its position, color, font size. Instead of creating a new object for each character in the document, only one object is created for each unique character, and its formatting characteristics are applied "externally".
import json // Example import, although not used in this code
// Flyweight interface
class Flyweight:
def operation(self, extrinsic_state): // Method accepting external state
pass
// ConcreteFlyweight
class ConcreteFlyweight(Flyweight):
def __init__(self, intrinsic_state):
self._intrinsic_state = intrinsic_state // Intrinsic state
def operation(self, extrinsic_state):
// Simulate operation considering external state
print(f"ConcreteFlyweight: Intrinsic state - {self._intrinsic_state}, Extrinsic state - {extrinsic_state}")
// FlyweightFactory
class FlyweightFactory:
_flyweights = {} // Cache of Flyweights
def get_flyweight(self, intrinsic_state):
if intrinsic_state not in self._flyweights:
print(f"FlyweightFactory: Creating a new flyweight for {intrinsic_state}")
self._flyweights[intrinsic_state] = ConcreteFlyweight(intrinsic_state) // Create new Flyweight
else:
print(f"FlyweightFactory: Reusing existing flyweight for {intrinsic_state}")
return self._flyweights[intrinsic_state] // Return existing or new Flyweight
Advantages:
- Reduces memory consumption by sharing common state.
- Decreases the number of objects created.
Disadvantages:
- Complicates code due to state sharing.
- Requires passing external state with each method call.
- May be redundant if the number of objects is small or their states vary greatly.