Published on

Learning Design Patterns: Flyweight Pattern - Little Resources, Big Heart

Authors

Flyweight Pattern is a Flexing way to express when the dev brothers don't want to use the words Cache - Caching - Memorization.

The Flyweight Pattern Story: Limited Resources, But You Need to Use a Lot

Let's go back in time to the beginning, when RAM and Hard Drives were scarce, how did the Game developers of that time face such Difficult challenges!

In a Game, just drawing a character requires going through a series of steps: loading the Texture from the hard drive, cropping (mapping Rect) the texture, and then drawing it on the screen. Imagine in games like Mario, Contra, or Car Racer, there are hundreds of characters appearing at the same time, each with its own Texture, would the machine at that time be able to handle it?

RAM fragmentation, the game lags terribly for sure!

So the OGs of Game Dev came up with a unique trick: put all the character's Textures into one giant Texture, load it only once, and then use metadata to cut out the correct piece of each character to draw.

Sound familiar? That's the original Flyweight Pattern! Although not yet named, this SHARE resource mindset to optimize performance was decades ahead of its time, helping games run smoothly on ancient machines and paving the way for top-notch graphics innovations later.

Applying Flyweight Pattern to the Present

In today's technological age, the Flyweight Pattern is not outdated at all, but on the contrary, it is extremely important in large-scale applications. Why? Because caching is the key to speeding up applications and providing a smooth user experience.

Think about it, technologies like Redis or CDN, in essence, are embodiments of the Flyweight principle. They share and reuse data, helping to optimize performance.

Closer to home, in mobile application development, managing the display of a large number of Bitmaps is a thorny problem. How to ensure Bitmaps are displayed accurately, completely and quickly? The answer is to use the most aggressive caching possible. And Caching, that's the Flyweight Pattern!

interface BitmapCache {
  fun putCache(key: String, bmp: Bitmap): Boolean
  fun retrieveCache(key: String): Bitmap?
  fun invalidate(): Unit
}

A Few Things to Note With the Flyweight Pattern

When applying the Flyweight Pattern, especially in caching scenarios, it is extremely important to carefully analyze the requirements of the problem. We need to accurately identify what type of data will be cached, thereby optimizing storage and retrieval strategies. The frequency of reading and writing data is also a key factor, influencing decisions about the cache's lifetime and synchronization mechanisms.

Clearly defining when and how to invalidate the cache is mandatory to ensure information accuracy. Finally, to avoid bottlenecks and improve performance, always prioritize asynchronous processing in the Flyweight Pattern.

I will write more articles on the topic of Cache on the blog @dantech. In this article, I hope you understand and grasp the core concept of the Flyweight Pattern is ok.

Good luck!