Flyweight Design Pattern in Ruby

1. Definition

The Flyweight Design Pattern minimizes memory usage by sharing as much data as possible with similar objects. It is a way to use objects in large numbers when a simple repeated representation would consume too much memory.

2. Problem Statement

In software systems, sometimes you may need to create a large number of similar objects. This can consume a lot of memory, especially when the objects only differ slightly.

3. Solution

The Flyweight pattern tackles this problem by separating the intrinsic state (shared) from the extrinsic state (external) of the objects. The intrinsic state remains constant across instances, while the extrinsic state is stored or computed externally and passed to the flyweight when required.

4. Real-World Use Cases

1. Text editors that handle large documents but avoid storing multiple instances of character styles or fonts.

2. Game platforms that need to render vast forests or terrains with many repeating elements but minimize memory usage.

5. Implementation Steps

1. Split the target class's attributes into intrinsic (shared) and extrinsic (unique).

2. Create a factory that caches and reuses instances of the class based on their intrinsic state.

6. Implementation in Ruby

# Flyweight class
class TreeType
  attr_reader :name, :color
  def initialize(name, color)
    @name = name
    @color = color
  end
  def display(x, y)
    "Displaying #{name} tree of #{color} color at (#{x}, #{y})."
  end
end
# Flyweight factory
class TreeFactory
  @@tree_types = {}
  def self.get_tree_type(name, color)
    key = [name, color].join('-')
    @@tree_types[key] ||= TreeType.new(name, color)
  end
end
# Client code
pine_tree = TreeFactory.get_tree_type("Pine", "Green")
oak_tree = TreeFactory.get_tree_type("Oak", "Brown")
puts pine_tree.display(5, 10)
puts oak_tree.display(10, 20)

Output:

Displaying Pine tree of Green color at (5, 10).
Displaying Oak tree of Brown color at (10, 20).

Explanation:

1. The TreeType class is the Flyweight. Its instances are shared based on name and color attributes.

2. TreeFactory maintains a collection of tree types and reuses them, ensuring that for each unique combination of name and color, only one TreeType instance is ever created.

3. The display method is an example of an operation that can be performed using both intrinsic (name, color) and extrinsic (x, y) states.

7. When to use?

Use the Flyweight pattern when:

1. An application needs to spawn a large number of similar objects.

2. The storage costs are high due to a vast amount of almost similar objects.

3. The object's states can be made extrinsic, and a few intrinsic states can be shared among many instances.


Comments