← Back to scenarios
ScenarioCatalog DB

Menu composite

Represent menu items and submenus together so the UI can render or invoke them consistently.

Problem

A menu system must render and invoke both individual menu items and nested submenus through a common component interface without special-case UI logic for each hierarchy level.

Related patterns

Implementations

Composite

TypeScriptApplication

Composite in TypeScript

Represents files and folders through one interface so callers can calculate the size of an individual file or an entire directory tree uniformly.

TypeScript
interface FileSystemNode {
  getName(): string;
  getSizeInBytes(): number;
}

class FileNode implements FileSystemNode {
  constructor(
    private readonly name: string,
    private readonly sizeInBytes: number,
  ) {}

  getName() {
    return this.name;
  }

  getSizeInBytes() {
    return this.sizeInBytes;
  }
}

class FolderNode implements FileSystemNode {
  private readonly children: FileSystemNode[] = [];

  constructor(private readonly name: string) {}

  getName() {
    return this.name;
  }

  add(child: FileSystemNode) {
    this.children.push(child);
  }

  getSizeInBytes() {
    return this.children.reduce(
      (total, child) => total + child.getSizeInBytes(),
      0,
    );
  }
}

const invoices = new FolderNode("invoices");
invoices.add(new FileNode("january.pdf", 120_000));
invoices.add(new FileNode("february.pdf", 140_000));

const archive = new FolderNode("archive");
archive.add(invoices);
archive.add(new FileNode("readme.txt", 2_000));

console.log(archive.getSizeInBytes());

Associated technologies