Flyweight The Problem Solution Example When to use?

Flyweight


The Problem:

Lets say we wanted to add tile effects for the Random Achievement game. More specifically, I want each terrain tile within the game to have different properties that can affect the gameplay such as hindering , enhancing, or even preventing movement. In addition, I also want to add textures for the tiles, instead of just having a plain color.

One common approach might be to define a Tile class and assign different attributes/methods to the various tiles we'll have in the game, and store each tile within a 2D array.

And this approach might be fine when we only have an "countable" amount of tiles within the world. But what if we expand our world to 1000 rows by 1000 cols? With one tile object (defined as shown below), a total of 48 bytes are required to store one tile in memory. With 1 million tiles thats 48MB memory used for the tiles objects alone! To put this into perspective, your average web browser with one tab opened takes about 300MB to 500MB.



The Solution

The idea behind the flyweight pattern is really simple, keep all the data that are shared between instances of the Tile class into it's own object, and have a pointer from each tile to the shared data object. For example, we can simply store the image path, movement property, and size into 4 different tile data object. Then have the type attribute of the tile itself to point to one of these objects. We now no longer repeatedly store copies of the same data into all the tiles instances!

Example:

When to use this pattern?

Whenever you're creating tons ( and I mean TONS!) of instances of an class, and there's shared static data between many of the instances, rather than storing a copy of those shared data in each instance, just stored them into a shared object.