Flyweight

Lets you fit more objects into the available amount of RAM by sharing common parts of state between multiple objects instead of keeping all of the data in each object.

classDiagram
    class FlyweightFactory {
        -cache
        +getFlyweight(repeatingState)
    }
    class Flyweight {
        -repeatingState
        +operation(uniqueState)
    }
    class Client {
        -uniqueState
    }

    FlyweightFactory o-- Flyweight
    Client --> FlyweightFactory
    Client ..> Flyweight

When to use

Use the Flyweight pattern only when your program must support a huge number of objects which barely fit into available RAM.

Explanation

Problem

To have some fun after long working hours, you decided to create a simple video game: players would be moving around a map and shooting each other. You chose to implement a realistic particle system and make it a distinctive feature of the game. Vast amounts of bullets, missiles, and shrapnel from explosions should fly all over the map and deliver a thrilling experience to the player.

Upon its completion, you pushed the last commit, built the game and sent it to your friend for a test drive. Although the game was running flawlessly on your machine, your friend could not play for long. On his computer, the game would crash after a few minutes of gameplay. After spending several hours digging through debug logs, you discovered that the game crashed because of an insufficient amount of RAM. It turned out that the particle system took too much memory.

Solution

The Flyweight pattern suggests that you stop storing the extrinsic state inside the object. Instead, you should pass this state to specific methods which rely on it. Only the intrinsic state stays within the object, letting you reuse it for different objects. Imagine that these objects differ only in their unique state, which usually has many variations, while their repeating state stays the same.

Real world problem

  1. Text Editor: Storing a heavy object for each character in a doc is 2GB for a simple file. Flyweight stores intrinsic font data once. Extrinsic (position, char code) is separate.
  2. Game Particles: As described above.
  3. Cache: Any system that caches and reuses objects based on keys.

Pros and Cons

Pros Cons
- RAM Savings: You can save lots of RAM, assuming your program has tons of similar objects. - CPU Overhead: You might be trading RAM over CPU cycles when some of the context data needs to be recalculated each time somebody calls a flyweight method.
- Complexity: The code becomes much more complicated. New team members will always be wondering why the state of an entity was separated in such a way.

Comparison

  • Singleton: Flyweight would resemble Singleton if you somehow managed to reduce all shared states of the objects to just one flyweight object. But there are crucial differences (Flyweights are immutable, Singleton is mutable).
  • Composite: Shared leaf nodes of the Composite tree can be implemented as Flyweights to save some RAM.

Code example

Typescript

Php