The Composite pattern is a structural design pattern that composes objects into tree structures to represent part-whole hierarchies. It allows clients to treat individual objects and compositions uniformly, simplifying interactions with complex, nested structures.
Core Intent
“Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.”
This pattern enables transparent recursion over hierarchical data, where leaves and composites are interchangeable.
When to Use Composite
| Scenario | Use Case |
|---|---|
| Hierarchical data structures exist | e.g., File systems, UI menus, product catalogs |
| Need to treat leaves and composites alike | Uniform operations (e.g., “render all”, “calculate total”) |
| Dynamic composition at runtime | Add/remove children without changing client code |
| Recursive operations on trees | Traverse and process nested elements |
| GUI components with nesting | Panels containing buttons, which contain icons |
Avoid when:
- Hierarchy is flat/simple → Overkill
- Operations differ significantly between leaves/composites → Use Visitor
Where It Is Used in Real Systems
| Domain | Example |
|---|---|
| File Systems | Directories (composite) containing files (leaf) |
| UI Frameworks | Panels (composite) with buttons/labels (leaf) |
| XML/HTML DOM | Elements (composite) with text nodes (leaf) |
| E-Commerce | Categories (composite) with products/subcategories (leaf) |
| Graphics | Groups (composite) of shapes (leaf) |
Key Benefits
- Uniformity: Single interface for leaves and composites
- Encapsulation: Hierarchy details hidden from clients
- Extensibility: Add new component types easily
- Simplified traversal: Recursive operations on trees
- Single Responsibility: Components manage own children
Real-World Example: E-Commerce Product Catalog Hierarchy
An e-commerce platform models a product catalog as a tree:
- Categories (e.g., “Electronics”) contain subcategories (e.g., “Laptops”) and products (e.g., “Dell XPS”).
- Operations like display catalog, calculate total inventory value, or search treat categories and products uniformly.
This allows dynamic nesting (add/remove products/categories) and recursive processing (e.g., total price across all subtrees).
C# Implementation
using System;
using System.Collections.Generic;
using System.Linq;
// ==================== COMPONENT ====================
public interface IProductComponent
{
string Name { get; }
decimal GetPrice();
void Display(int indent = 0);
void Add(IProductComponent component);
void Remove(IProductComponent component);
IEnumerable<IProductComponent> GetChildren();
}
// ==================== LEAF ====================
public class ProductItem : IProductComponent
{
public string Name { get; }
private readonly decimal _price;
public ProductItem(string name, decimal price)
{
Name = name;
_price = price;
}
public decimal GetPrice() => _price;
public void Display(int indent = 0)
{
Console.WriteLine(new string(' ', indent * 2) + $"└── Product: {Name} - ₹{_price:F2}");
}
public void Add(IProductComponent component)
=> throw new InvalidOperationException("Products cannot have children.");
public void Remove(IProductComponent component)
=> throw new InvalidOperationException("Products cannot have children.");
public IEnumerable<IProductComponent> GetChildren() => Enumerable.Empty<IProductComponent>();
}
// ==================== COMPOSITE ====================
public class ProductCategory : IProductComponent
{
public string Name { get; }
private readonly List<IProductComponent> _children = new();
public ProductCategory(string name)
{
Name = name;
}
public decimal GetPrice()
{
return _children.Sum(child => child.GetPrice());
}
public void Display(int indent = 0)
{
Console.WriteLine(new string(' ', indent * 2) + $"┌── Category: {Name} (Total: ₹{GetPrice():F2})");
foreach (var child in _children)
{
child.Display(indent + 1);
}
}
public void Add(IProductComponent component)
{
_children.Add(component);
}
public void Remove(IProductComponent component)
{
_children.Remove(component);
}
public IEnumerable<IProductComponent> GetChildren() => _children;
}
// ==================== CLIENT ====================
public class CatalogManager
{
private readonly IProductComponent _root;
public CatalogManager(IProductComponent root)
{
_root = root;
}
public void DisplayCatalog()
{
_root.Display();
}
public decimal GetTotalCatalogValue()
{
return _root.GetPrice();
}
public void AddToCatalog(IProductComponent component)
{
if (_root is ProductCategory category)
category.Add(component);
}
}
// ==================== DEMO ====================
class Program
{
static void Main()
{
// Build hierarchy
var electronics = new ProductCategory("Electronics");
var laptops = new ProductCategory("Laptops");
laptops.Add(new ProductItem("Dell XPS", 120000m));
laptops.Add(new ProductItem("MacBook Pro", 150000m));
var phones = new ProductCategory("Phones");
phones.Add(new ProductItem("iPhone 15", 80000m));
phones.Add(new ProductItem("Samsung S24", 70000m));
electronics.Add(laptops);
electronics.Add(phones);
var manager = new CatalogManager(electronics);
Console.WriteLine("=== COMPOSITE PATTERN IN E-COMMERCE ===\n");
manager.DisplayCatalog();
Console.WriteLine($"\nTotal Catalog Value: ₹{manager.GetTotalCatalogValue():F2}");
}
}Sample Output
=== COMPOSITE PATTERN IN E-COMMERCE ===
┌── Category: Electronics (Total: ₹470000.00)
├── Category: Laptops (Total: ₹270000.00)
│ └── Product: Dell XPS - ₹120000.00
│ └── Product: MacBook Pro - ₹150000.00
├── Category: Phones (Total: ₹150000.00)
└── Product: iPhone 15 - ₹80000.00
└── Product: Samsung S24 - ₹70000.00
Total Catalog Value: ₹470000.00UML Class Diagram

Participants in the Composite Pattern
The classes and objects participating in this pattern include:
- Component (IProductComponent)
- Declares the common interface for both leaf and composite objects.
- Defines operations like Display(), GetPrice().
- Leaf (ProductItem)
- Represents primitive elements with no children.
- Implements component operations directly.
- Composite (ProductCategory)
- Defines behavior for components with children.
- Stores child components and delegates operations (e.g., sum prices recursively).
- Client
- Works with Component references, unaware of leaf vs. composite.
Summary Table
| Participant | Role in E-Commerce Example |
|---|---|
| Component | IProductComponent – common interface for products/categories |
| Leaf | ProductItem – atomic product with price |
| Composite | ProductCategory – container for sub-items |
| Client | CatalogManager – operates on hierarchy uniformly |
Advantages in E-Commerce
| Benefit | Impact |
|---|---|
| Scalable catalogs | Nest categories dynamically |
| Uniform operations | Search/display across entire tree |
| Recursive queries | Total value, inventory count |
| Extensible | Add new component types (e.g., bundles) |
Composite vs Decorator
| Aspect | Composite | Decorator |
|---|---|---|
| Structure | Tree hierarchy (part-whole) | Wrapper chain (add behavior) |
| Purpose | Group objects | Enhance single object |
| Example | Catalog tree | Product with wrapper (e.g., discount) |
| Children | Many (recursive) | Single (linear) |
Conclusion
The Composite pattern is ideal for e-commerce catalogs, where nested categories and products form a tree. It provides transparent handling of hierarchies, enabling efficient traversal and operations while maintaining flexibility for dynamic content management.
Employed in ASP.NET Core (view components), XML parsers, and e-commerce platforms like Shopify for menu/product trees.




