The Problem
Tree-shaped data appears everywhere: category hierarchies, organization charts, nested menu structures, and bundle catalogs. Without a common contract, callers need different code paths for leaves and groups, which makes traversal and aggregation noisy.
The Solution
Composite gives both leaves and containers a shared interface. In Go, that often means a small behavior contract plus one composite type that recursively stores children. The caller can then calculate totals or render structure without caring whether it is visiting one node or a whole branch.
Structure
- Component interface:
CatalogNodedefines the behavior common to leaves and groups. - Leaf:
Producthas no children and returns its own price. - Composite:
Categorystores child nodes and aggregates over them. - Client: Traverses the tree through the shared interface.
Implementation
This example models a nested catalog where categories can contain products or subcategories. The same interface supports recursive rendering and total price aggregation for the entire tree.
package main
import "strings"
type CatalogNode interface {
Price() int
Render(level int) string
}
func pad(level int) string {
return strings.Repeat(" ", level)
} Best Practices
- Keep the component interface small so both leaves and composites can implement it naturally.
- Let the composite own recursion. Clients should not need special cases for children.
- Avoid stuffing child-management methods into the shared interface unless leaves can handle them sensibly.
- Use Composite for real tree structures, not just any list of items.
- If traversal logic grows complex, pair Composite with Iterator or Visitor instead of bloating the node interface.
When to Use
- You work with tree-shaped data and want uniform treatment of leaves and branches.
- Aggregation or rendering should work recursively across nested groups.
- Callers should not need explicit leaf-versus-composite branching.
When NOT to Use
- The data is not naturally hierarchical.
- A flat slice and helper functions would be simpler.
- The shared interface would force unnatural methods onto leaves.