Flyweight

The flyweight pattern

The flyweight pattern is a structural pattern and is used to share large resources when using many objects of similar types.

Tree image

A simple example could be a word processor, imagine the letter 'e' which would appear many times within a document, and so the objects for each 'e' constructed would have an intrinsic state (invariant) the 'e' glyph and an extrinsic state (variant) such as the colour and position in the document.

Another example could be an image on a webpage that is a very large (like a map or collage), the image could be broken into smaller images, with the smaller images used many times to dynamically form the larger image.
Ignoring browser caching, we'll utilise the flyweight pattern, to prevent the larger image taking too long to load and stopping the user losing interest and moving on to another webpage.
So lets attempt to emulate this using JavaScript and downloading a large image that's broken-up into smaller images and then randomly showing the smaller images to form a larger picture.
Now I've made four simple images and I will combine them into a pattern, the HTML and the images are:
<img id='redImage' src='RedShade.png' />
<img id='greenImage' src='GreenShade.png' />
<img id='blueImage' src='BlueShade.png' />
<img id='blackImage' src='BlackShade.png' />

The client will be the webpage document, the FlyweightFactory will be called the ImageFactory the JavaScript being:
var imageFactory = function () {
  this.flyweightImages = [];
  this.getFlyweight = function (key) {
    if (!this.flyweightImages[key]) {
      this.flyweightImages[key] = new imageElement(key);
    }
    return this.flyweightImages[key];
  }
}
The ConcreteFlyweights will be instances of imageElement which use the Javascript cloneNode function, which creates a copy of a HTML element.
var imageElement = function (element) {
  this.element = document.getElementById(element);
  this.draw = function (location) {
    var clonedElement = this.element.cloneNode(true);
    clonedElement.style.position = 'absolute';
    clonedElement.style.top = location.top;
    clonedElement.style.left = location.left;
    document.getElementById('flyweightImage').appendChild(clonedElement);
  }
}
We'll call the method draw(location) with location being the extrinsic state of the imageElement to place an image at particular place on the document.

Summary

The flyweight pattern is a useful pattern for storing large objects that have to be reused and it could be argued that it could be called the 'caching pattern'.

References

wiki
Design Patterns [GOF]
sourcemaking flyweight pattern
geeksforgeeks flyweight pattern
TypeScript