Author: David Martinez
Created: June 29, 2024 - Updated: June 30, 2024
Read Time: 12 min
Welcome! Today, let's embark on a journey into the Flyweight design pattern. We'll dive deep into its workings, explore real-world scenarios, and unveil its magic!
The Flyweight is a structural design pattern that allows you to fit more objects into the available amount of RAM by sharing as much data as possible with other similar objects.
It is particularly useful when dealing with a large number of objects that share common properties, optimizing memory usage.
🔸 Use this pattern when your program needs to support a large number of fine-grained objects efficiently.
🔸 It's beneficial when many objects share common state, which can be extracted and stored externally.
Consider developing a shooter video game where particles (such as bullets) are rendered as new objects for each instance. This leads to high memory consumption and eventually crashes the game on devices with limited RAM.
The Flyweight pattern suggests sharing common state between multiple objects, reducing the memory footprint. For our shooter game, we can extract the common properties of particles and share them across instances.
In this example, the Flyweight pattern is utilized to manage the particles in a shooter game.
🔹 The Flyweight interface declares methods that the shared and unique parts of the state will implement.
🔹 Concrete Flyweight objects implement the Flyweight interface and store the shared state.
🔹 The Flyweight Factory manages the Flyweight objects and ensures the reuse of shared objects.
🔹 Client code uses the Flyweight objects to render particles efficiently.
1️⃣ Extract the common properties of the particles and store them in shared Flyweight objects.
2️⃣ The Flyweight Factory manages these shared objects, ensuring reuse rather than creating new instances.
3️⃣ The client code uses Flyweight objects to render particles, passing unique properties as needed.
💡 Note: The Flyweight pattern can significantly reduce memory consumption by sharing common data between objects.
🔮 Optimizes memory usage by sharing common data between multiple objects.
🔮 Reduces the overhead of object creation, enhancing performance.
🔮 Facilitates managing a large number of objects efficiently.
🔮 Aligns with the principle of least astonishment by minimizing memory footprint.
🔮 Encourages the separation of intrinsic (shared) and extrinsic (unique) state, promoting cleaner code.
# Flyweight interfaceclass ParticleFlyweightdef render(x, y)raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"endend# Concrete Flyweightclass BulletParticle < ParticleFlyweightdef initialize(image)@image = imageenddef render(x, y)puts "Rendering Bullet at (#{x}, #{y}) with image #{@image}"endend# Flyweight Factoryclass ParticleFactorydef initialize@particles = {}enddef get_particle(image)@particles[image] ||= BulletParticle.new(image)endend# Client codeclass Gamedef initialize(factory)@factory = factory@particles = []enddef create_bullet(x, y, image)particle = @factory.get_particle(image)@particles << { particle: particle, x: x, y: y }enddef render@particles.each do |p|p[:particle].render(p[:x], p[:y])endendend# Example Usagedef mainfactory = ParticleFactory.newgame = Game.new(factory)game.create_bullet(10, 20, 'bullet.png')game.create_bullet(15, 25, 'bullet.png')game.create_bullet(20, 30, 'bullet.png')game.renderendmain# Output# Rendering Bullet at (10, 20) with image bullet.png# Rendering Bullet at (15, 25) with image bullet.png# Rendering Bullet at (20, 30) with image bullet.png
The Flyweight pattern allows efficient memory usage by sharing as much data as possible with other similar objects.
🔺 This pattern is advantageous when dealing with a large number of fine-grained objects that share common properties.
🔺 It's beneficial when optimizing memory consumption and enhancing performance.
🔺 The Flyweight pattern aligns with the principle of least astonishment by minimizing memory footprint and promoting cleaner code.
🔺 By embracing the Flyweight pattern, you can efficiently manage a large number of objects while optimizing memory usage.
💻 You can find this and other design patterns here 📚