Skip to main content

Flyweight pattern

· 4 min read
Esteban Gonzalez
Collaborator

Example

This image is part of the game この素晴らしい世界に祝福を! Attack of the Destroyer developed by Entergram

The objective of this post is to explain and show how to implement the Flyweight Pattern in a basic way and see how this pattern can help you to reduce the memory usage of your applications.

Pre-requisites

Check all the description and information related to the Flyweight Pattern and return here to see a practical example.

Description

Let's continue with the example given on the Flyweight docs, Imagine we are developing a video game inspired by the popular anime "Konosuba". In this game, players control multiple main characters like Kazuma, Aqua, Darkness, and Megumin. During the latest release includes new enemies, Npcs, Allies, dungeons, levels, etc. With this new release you received too many tickets where the users report that the game is crashing, when you check the analysis from the store all the users that reported the issue are users with less than 8Gb of Ram.

When you start fixing the bug as soon as possible to avoid losing users, you discover that the game works as expected, no memory leaks, no problems with garbage collection, etc. After having no idea how to fix this problem, you discover that the enemies and dungeons added in the latest version consume too many resources. But the enemies are ok and the same with the dungeons. After trying to understand the reason you remember the flyweight pattern. On our videogame we have playabe characters like Darkness, Aqua, Kazuma, Megumin, etc. Then we have the Non playable characters or NPC like Goblins, Villagers, Shopkeepers, etc. But all of them have common attributes with intrinsic states.

So you decide to implement this pattern on the NPC characters to reduce the memory usage.

Code Implementation

To implement this pattern you will need:

  • Flyweight Interface
  • ConcreteFlyweight: It represents the shared (intrinsic) part of an NPC character.
  • Flyweight Factory: Responsible for creating and managing Flyweight objects. It ensures that Flyweight objects are shared properly to minimize memory usage.
  • Extrinsic State: Holds the extrinsic state of an NPC character. These attributes are specific to each instance and are provided to the Flyweight during rendering.

This could be the original implementation of the code without Flyweight pattern

Results

When you implement this pattern you will have a notorious reduction of the memory usage of your applications

BenchmarkResult

Implementing this pattern reduces you 569 bytes more.

note

Please visit the code implementation of the benchmark, also this result could be more notoriuos using another example that requires more memory like a real videogame.

Bonus

Why don't you apply the flyweight pattern on the other characters like Darkness, Aqua, Megumin, Kazuma, etc?

On the section Flyweight cons we mention Limited Flexibility

If each character in a game requires a unique set of graphical assets or abilities, the Flyweight pattern would not be applicable.

So in this case each playable character like Darkness or Aqua have some special attributes that cannot be generic like the animations, assets, abilities, etc. So if we implement this pattern here all the characters look like the same and that's not the idea.

but.... For the NPC or the enemies this feature is valid because we do not need to focus on making a skeleton or goblin enemy to be different, and they all have the same attributes perhaps. Also it's important to consider that in our game we have the same enemy multiple times but the playable character appears maximum one time because they can be played by the user or supporting the user.

That's all

This image is part of この素晴らしい世界に祝福を! Season 2 produced by Studio Deen

That's all folks, I hope you have learned about the Flyweight pattern from this small example.