← Back to scenarios
ScenarioCatalog DB

Tree rendering flyweight

Share tree-type data across many tree instances to reduce memory use in a forest renderer.

Problem

A forest renderer must represent many trees efficiently by sharing repeated type data such as appearance and species while storing only instance-specific state such as position separately.

Related patterns

Implementations

Flyweight

TypeScriptApplication

Flyweight in TypeScript

Reuses shared text-style objects across many document characters while each character retains only its unique position and content.

TypeScript
type TextStyleKey = {
  fontFamily: string;
  fontSize: number;
  color: string;
};

class TextStyle {
  constructor(
    readonly fontFamily: string,
    readonly fontSize: number,
    readonly color: string,
  ) {}

  render(character: string, position: number) {
    console.log(
      `Rendering "${character}" at ${position} with ${this.fontFamily} ${this.fontSize}px ${this.color}`,
    );
  }
}

class TextStyleFactory {
  private readonly styles = new Map<string, TextStyle>();

  getStyle(key: TextStyleKey): TextStyle {
    const cacheKey = `${key.fontFamily}:${key.fontSize}:${key.color}`;
    const existing = this.styles.get(cacheKey);

    if (existing) {
      return existing;
    }

    const style = new TextStyle(
      key.fontFamily,
      key.fontSize,
      key.color,
    );

    this.styles.set(cacheKey, style);
    return style;
  }
}

class DocumentCharacter {
  constructor(
    private readonly value: string,
    private readonly position: number,
    private readonly style: TextStyle,
  ) {}

  render() {
    this.style.render(this.value, this.position);
  }
}

const styles = new TextStyleFactory();
const headingStyle = styles.getStyle({
  fontFamily: "Inter",
  fontSize: 24,
  color: "#ffffff",
});

const firstCharacter = new DocumentCharacter("H", 0, headingStyle);
const secondCharacter = new DocumentCharacter("i", 1, headingStyle);

firstCharacter.render();
secondCharacter.render();

Associated technologies