Minggu, 20 April 2025

Composite Pattern

| Minggu, 20 April 2025

The Composite Pattern with real-world scenarios you already know, then see how it works in software.

📖 What Is the Composite Pattern (Simple Explanation)

The Composite Pattern lets you treat individual objects and groups of objects the same way.

It builds tree-like structures where:

  • Leaf nodes are individual things (like a button, a file, a single employee)
  • Composite nodes are collections of other things (like a panel with multiple buttons, a folder with files, or a manager with employees)

🎨 Real-World Examples (Easy to Visualize)

📁 1. File System (Folders & Files)

  • File — an individual document (leaf)
  • Folder — a container holding files or other folders (composite)

You can open, move, or delete both files and folders — even though a folder contains more things inside.

➡️ File and Folder both follow the same interface:

  • open()
  • delete()
  • getSize()

But a folder recursively calls those methods on its contents.

🧑‍💼 2. Company Organizational Chart

  • Employee — an individual staff member (leaf)
  • Manager — has multiple subordinates (composite)

Both employees and managers can:

  • getName()
  • getSalary()
  • showDetails()

But a manager does this by delegating to its team.

🧱 3. UI Layout

  • Button, Label, TextBox — UI elements (leaves)
  • Panel, Form, Page — contain other UI elements (composites)

You can render, move, or hide both individual components and entire panels in the same way.

🖥️ Code Concept Behind This

Let’s pick the File System case and model it in TypeScript using the Composite Pattern.

interface FileSystemItem {
  show(indent?: string): void;
}

class File implements FileSystemItem {
  constructor(private name: string) {}

  show(indent: string = '') {
    console.log(`${indent}- ${this.name}`);
  }
}

class Folder implements FileSystemItem {
  private items: FileSystemItem[] = [];

  constructor(private name: string) {}

  add(item: FileSystemItem) {
    this.items.push(item);
  }

  show(indent: string = '') {
    console.log(`${indent}+ ${this.name}`);
    this.items.forEach(item => item.show(indent + '  '));
  }
}

// Usage
const file1 = new File('Resume.pdf');
const file2 = new File('CoverLetter.docx');

const folder = new Folder('Job Applications');
folder.add(file1);
folder.add(file2);

const mainFolder = new Folder('Documents');
mainFolder.add(folder);
mainFolder.add(new File('Photo.jpg'));

mainFolder.show();

Console Output:

+ Documents
  + Job Applications
    - Resume.pdf
    - CoverLetter.docx
  - Photo.jpg

🎯 Why Is This Useful?

✅ You can treat both a file and a folder the same way (show())

✅ Easy to build hierarchies

✅ Great for recursive structures like:

  • Filesystem
  • UI Layouts
  • Organization Trees
  • Nested Menus
  • Multi-step Forms ✅ It lets you write simpler, cleaner, and scalable code

✅ Summary

Concept Leaf Composite
File System File Folder
Company Employee Manager
UI Layout Button / Text Panel / Form
Task List Simple Task Grouped Tasks
Menu Single Menu Item Submenu

👉 Composite Pattern makes hierarchical structures uniform and easy to manage


Related Posts

Tidak ada komentar:

Posting Komentar