Share the heavy, unchanging parts of many similar objects instead of duplicating them per instance.
Rendering a page of text as one object per character, each holding its own copy of the font's full glyph bitmap, wastes enormous memory — most of that data (the glyph shape) is identical across every 'a' on the page. Only the position differs per character.
The unchanging, shareable part (intrinsic state — the glyph shape) lives in one flyweight object, reused by every occurrence. The part that varies per instance (extrinsic state — x/y position) is passed in from the outside at use time instead of stored on the flyweight.
The factory caches one flyweight per character; a million on-screen letters reuse just 26 shared glyph objects.
class Glyph {
constructor(char) {
this.char = char;
this.bitmap = `<expensive bitmap data for '${char}'>`; // shared, loaded once
}
drawAt(x, y) {
console.log(`drawing '${this.char}' at (${x}, ${y})`);
}
}
class GlyphFactory {
static #cache = new Map();
static get(char) {
if (!GlyphFactory.#cache.has(char)) {
GlyphFactory.#cache.set(char, new Glyph(char));
}
return GlyphFactory.#cache.get(char);
}
}
function renderText(text) {
let x = 0;
for (const char of text) {
GlyphFactory.get(char).drawAt(x, 0); // extrinsic position, passed in
x += 8;
}
}
renderText("hello hello"); // only 5 distinct Glyph objects created ('h','e','l','o',' ')