menu
Behavioralarrow_forward_ios
Flyweight
network_pingFlyweight

Description

Structural design pattern that allows you to reduce RAM consumption by sharing states between similar objects.
Flyweight is one of the lesser-used design patterns because of its use. With today’s computing power, we rarely think about the performance of our computers

Coding Example

Let’s assume we have a Canvas on which we want to draw. In order to draw something, we need to put some Color in the right places. So we’ll create a Color class that takes a hexadecimal value as the only attribute.

class Color
  attr_reader :hex

  def initialize(hex)
    @hex = hex
  end
end
Now let’s imagine we want to cover the entire canvas with a resolution of 1000 x 1000 in black.

class Canvas 
  def draw(x:, y:, color:)
    # Draw color on provided coordinates
  end
end

canvas = Canvas.new

1000.times do |x|
  1000.times do |y|
    canvas.draw(x: x, y: y, color: Color.new('#000000'))
  end
end
A canvas created in this way will create as many as a million objects of the Color class. However, we can avoid this with the Flyweight pattern, which allows us to do this using only one object.
So now let’s create a ColorFactory(flyweight factory) class that will be responsible for color distribution.

class ColorFactory
  attr_reader :colors

  def initialize
    @colors = {}
  end
  
  def find_color(hex)
    if colors.has_key?(hex)
      color = colors[hex]
    else
      color = Color.new(hex)
      colors[hex] = color
    end

    color
  end
end
This class will store the already created colors, but not in the form of an array, but in the form of a hash. The find_color method will check if a given color already exists and will create a new object only if it has not been created before and add it to the colors hash.
Now using the factory class we are able to create an all-black canvas using only one object.

class Canvas
  attr_reader :color_factory

  def initialize
    @color_factory = ColorFactory.new
  end
  
  def draw(x:, y:, color:)
    color = color_factory.find_color(color)
    
    # Draw color on provided coordinates
  end
end

canvas = Canvas.new

1000.times do |x|
  1000.times do |y|
    canvas.draw(x: x, y: y, color: '#000000')
  end
end