Design Patterns in Ruby | FLYWEIGHT 💿
rubyhub.io
Posted on August 21, 2023
Overview
Flyweight is a structural design pattern that allows you to reduce RAM consumption by sharing states between similar objects.
It 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 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
Posted on August 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 3, 2024